Skip to content

Modal.Queue reference

Source: packages/modal/src/CreateQueue.ts

Create queues by name at runtime: one per user, session or task. Modal’s native shape is get-or-create by name, so getOrCreate is idempotent and safe to call on every request.

Bind it to a Modal.Environment to keep these runtime objects in their own namespace (or to nothing, for the workspace’s default environment). They aren’t in Alchemy state: deleting the environment removes them.

Objects created at run time are tagged with the stack, stage and binding (alchemy::stack, alchemy::stage, alchemy::id) and are not deleted when the stack is destroyed. A Modal queue has only a name, so the tags become its name prefix, Modal.runtimePrefix({ stack, stage, id }): list them with modal queue list and delete the ones whose name starts with it.

import * as Cloudflare from "@alchemy.run/cloudflare";
import * as Modal from "@alchemy.run/modal";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import { HttpServerRequest } from "effect/http/HttpServerRequest";
import * as HttpServerResponse from "effect/http/HttpServerResponse";
import { Agents, Coder } from "./Coder.ts";
export default class Api extends Cloudflare.Worker<Api>()(
"Api",
{ main: import.meta.url },
Effect.gen(function* () {
const queues = yield* Modal.CreateQueue(Agents);
const sandboxes = yield* Modal.CreateSandbox(Coder);
return {
fetch: Effect.gen(function* () {
const request = yield* HttpServerRequest;
const user = request.headers["x-user"] ?? "anonymous";
const inbox = yield* queues.getOrCreate(`inbox-${user}`);
yield* inbox.put({ task: "review" });
return HttpServerResponse.text("ok");
}).pipe(Effect.orDie),
};
}).pipe(Effect.provide(Layer.mergeAll(Modal.CreateQueueHttp, Modal.CreateSandboxHttp))),
) {}

Source: packages/modal/src/CreateQueueHttp.ts Kind: Layer · Provides: Modal.CreateQueue

CreateQueue over Modal’s API. Grants the host’s identity (a scoped Modal.ServiceUser) the contributor role on the environment.

Source: packages/modal/src/Queue.ts

A Modal Queue: a distributed FIFO queue shared by every container, Sandbox and client in the workspace, with optional named partitions. Items expire 24 hours after they are put (partitions can set their own TTL).

Bind it with WriteQueue to put items, ReadQueue to take them, or ReadWriteQueue for both, from a Worker, Lambda or any other runtime. Values travel as bytes: the bindings encode them as JSON by default.

Modal queues have no tags. Ownership is inferred from Alchemy state: a queue found under an explicit name without prior state is reported as unowned.

A queue with a generated name

import * as Modal from "@alchemy.run/modal";
export const Jobs = Modal.Queue("Jobs", {});

A named queue in an environment

import * as Modal from "@alchemy.run/modal";
export const Agents = Modal.Environment("Agents", {});
export const Tasks = Modal.Queue("Tasks", { name: "tasks", environment: Agents });
import * as Cloudflare from "@alchemy.run/cloudflare";
import * as Modal from "@alchemy.run/modal";
import * as Effect from "effect/Effect";
import * as HttpServerResponse from "effect/http/HttpServerResponse";
import { Jobs } from "./Storage.ts";
export default class Api extends Cloudflare.Worker<Api>()(
"Api",
{ main: import.meta.url },
Effect.gen(function* () {
const jobs = yield* Modal.WriteQueue(Jobs);
return {
fetch: Effect.gen(function* () {
yield* jobs.put({ repo: "alchemy-run/alchemy", command: "pnpm test" });
return HttpServerResponse.text("queued");
}).pipe(Effect.orDie),
};
}).pipe(Effect.provide(Modal.WriteQueueHttp)),
) {}

Queue.lookup references a queue Alchemy doesn’t manage (created with the Modal CLI or by another stack). It is read during plan/deploy, never created, updated or deleted.

const jobs = Modal.Queue.lookup({ name: "jobs" });

Source: packages/modal/src/ReadQueue.ts

Take items from a Modal Queue from any runtime: take (removes), peek and len. Items are JSON.

import * as Cloudflare from "@alchemy.run/cloudflare";
import * as Modal from "@alchemy.run/modal";
import * as Effect from "effect/Effect";
import * as HttpServerResponse from "effect/http/HttpServerResponse";
import { Jobs } from "./Storage.ts";
export default class Api extends Cloudflare.Worker<Api>()(
"Api",
{ main: import.meta.url },
Effect.gen(function* () {
const queue = yield* Modal.ReadQueue(Jobs);
return {
fetch: Effect.gen(function* () {
const [job] = yield* queue.take({ timeout: "5 seconds" });
return yield* HttpServerResponse.json(job ?? null);
}).pipe(Effect.orDie),
};
}).pipe(Effect.provide(Modal.ReadQueueHttp)),
) {}

Source: packages/modal/src/ReadQueueHttp.ts Kind: Layer · Provides: Modal.ReadQueue

ReadQueue over Modal’s API. Grants the host’s identity (a scoped Modal.ServiceUser) the contributor role on the queue’s environment.

Source: packages/modal/src/ReadWriteQueue.ts

Put and take items on a Modal Queue from any runtime. Items are JSON.

import * as Cloudflare from "@alchemy.run/cloudflare";
import * as Modal from "@alchemy.run/modal";
import * as Effect from "effect/Effect";
import * as HttpServerResponse from "effect/http/HttpServerResponse";
import { Jobs } from "./Storage.ts";
export default class Api extends Cloudflare.Worker<Api>()(
"Api",
{ main: import.meta.url },
Effect.gen(function* () {
const queue = yield* Modal.ReadWriteQueue(Jobs);
return {
fetch: Effect.gen(function* () {
yield* queue.put({ n: 1 });
const items = yield* queue.take({ count: 10 });
return yield* HttpServerResponse.json(items);
}).pipe(Effect.orDie),
};
}).pipe(Effect.provide(Modal.ReadWriteQueueHttp)),
) {}

Source: packages/modal/src/ReadWriteQueueHttp.ts Kind: Layer · Provides: Modal.ReadWriteQueue

ReadWriteQueue over Modal’s API. Grants the host’s identity (a scoped Modal.ServiceUser) the contributor role on the queue’s environment.

Source: packages/modal/src/WriteQueue.ts

Put items into a Modal Queue from any runtime. Items are JSON, so a Python consumer reads them with json.loads.

import * as Cloudflare from "@alchemy.run/cloudflare";
import * as Modal from "@alchemy.run/modal";
import * as Effect from "effect/Effect";
import * as HttpServerResponse from "effect/http/HttpServerResponse";
import { Jobs } from "./Storage.ts";
export default class Api extends Cloudflare.Worker<Api>()(
"Api",
{ main: import.meta.url },
Effect.gen(function* () {
const queue = yield* Modal.WriteQueue(Jobs);
return {
fetch: Effect.gen(function* () {
yield* queue.put({ repo: "alchemy-run/alchemy", command: "pnpm test" });
return HttpServerResponse.text("queued");
}).pipe(Effect.orDie),
};
}).pipe(Effect.provide(Modal.WriteQueueHttp)),
) {}

Source: packages/modal/src/WriteQueueHttp.ts Kind: Layer · Provides: Modal.WriteQueue

WriteQueue over Modal’s API. Grants the host’s identity (a scoped Modal.ServiceUser) the contributor role on the queue’s environment.