---
title: Queues
description: "Send messages with env.NAME.send, consume them with a queue handler."
---

## Configuration

```jsonc
"queues": ["JOBS"]
```

Bare names are auto-provisioned on deploy; see [Storage resources](/docs/storage).

## Sending

```js
env.JOBS.send({ type: "email", to: address }, { delaySeconds: 30 });
env.JOBS.sendBatch([{ body: a }, { body: b, delaySeconds: 5 }]);
```

Non-string bodies are sent as JSON. `send` returns once the message is stored; delivery happens separately.

## Consuming

Consume messages with a `queue` handler on the same default export as `fetch`. Each message's `body` arrives already parsed from JSON:

```js
queue(batch) {
  for (const msg of batch.messages) {
    try { handle(msg.body); msg.ack(); }
    catch { msg.retry(); }
  }
}
```

## Delivery

- Messages arrive in batches of up to 10.
- A message the handler neither acks nor retries counts as acked, including when the handler throws.
- A retried message is delivered again after about 5 seconds. After 5 attempts it is dropped.

## Methods

| Method | Signature | Notes |
| --- | --- | --- |
| `send` | `(body, { delaySeconds? })` | One message. |
| `sendBatch` | `(messages[])`, each `{ body, delaySeconds? }` | Several messages. |
| `msg.ack()` | | Mark a message handled. |
| `msg.retry()` | | Deliver it again later. |
| `batch.ackAll()`, `batch.retryAll()` | | The same for every message in the batch. |

Each message also has `id` and `timestamp`.

## Related

- [The handler](/docs/concepts/handler): the full `fetch`, `scheduled` and `queue` export
