Skip to main content
Cloudflare Queues is a durable, at-least-once message queue built for Workers. Your Blaze routes act as producers — they enqueue a message and immediately return a response to the client — while a separate consumer function processes those messages in batches on its own schedule. This decoupling keeps your HTTP responses fast and moves expensive or unreliable work (sending emails, calling third-party APIs, running data pipelines) out of the critical path.

Configure the binding

1

Declare producers and consumers in wrangler.toml

wrangler.toml
2

Define the Env type

src/types/env.ts
3

Pass Env to createApp

src/index.ts

Producing messages

Call req.env.QUEUE.send(body) from any route handler to enqueue a message. The call is asynchronous but lightweight — it does not wait for the consumer to process the message. Return a 202 Accepted to signal to the client that the work has been queued, not completed.

Sending multiple messages at once

Use req.env.QUEUE.sendBatch(messages) to enqueue up to 100 messages in a single call. Each item in the array must be an object with a body property. Batching is more efficient than calling .send() in a loop because the entire batch is written to disk in one round-trip.
A single sendBatch call can contain up to 100 messages. Each individual message body must be under 128 KB, and the total size of the batch cannot exceed 256 KB. For larger workloads, split the array into chunks and call sendBatch once per chunk.

Consuming messages

Wire the consumer alongside app.fetch in your default export. The queue function receives a MessageBatch containing up to max_batch_size messages. Call msg.ack() after successful processing to prevent redelivery.
src/index.ts
The queue consumer runs in a separate invocation from your HTTP handlers — it is not part of the Blaze middleware chain. It receives the raw env object directly, not a BlazeRequest. You can still call any binding on env (D1, KV, R2, AI) from within the consumer.

Typed message bodies

The Queue<T> generic flows from your Env type into both req.env.QUEUE.send() and the MessageBatch<T> argument in the consumer, giving you end-to-end type safety without extra casting.

Dead letter queues

When a message exceeds max_retries, Cloudflare automatically moves it to the dead letter queue specified in wrangler.toml. Inside your consumer, call msg.retry() to explicitly requeue a failed message for another attempt, or msg.ack() to discard it even when processing failed (useful for intentionally skipping malformed messages).
Configure the dead letter queue in wrangler.toml so permanently failed messages are preserved for inspection:
wrangler.toml
When a queue send does not need to complete before you return a response, use req.ctx.waitUntil() to fire it in the background. This is useful for low-priority analytics or audit events where you want to accept the HTTP response immediately and let the enqueue happen concurrently.