---
title: Queues
description: Create a managed message queue for workers and scheduled jobs, choose how long it hides and keeps messages, and connect services to it.
section: Data
order: 5
---

A queue holds work for workers and scheduled jobs to take, with visibility timeouts and dead letters handled by Dekka instead of your code. Like a bucket, it's reached at your region's HTTPS endpoint, and only services you connect to it get a token.

> [!NOTE]
> Queues are simulated for now. Dekka creates the queue and gives each connection its token, but nothing holds or delivers messages yet, so a service that sends to `QUEUE_URL` reaches nothing until queues leave simulation.

## Create a queue

On the canvas, choose **Add**, then **Queue**. Give it a name, choose a **Visibility timeout** and how long to **Keep messages for**, enter a number under **Move to dead letters after** if messages that keep failing should be set aside, and choose **Create queue**. Unless you choose otherwise, a new queue hides a received message for 30 seconds, keeps messages for four days and never moves them to dead letters.

To create one with the API, send the spec to `POST /v1/projects/{project_id}/resources`. Without an `environment_id`, the queue goes in the project's default environment.

```bash
curl https://api.dekka.cloud/v1/projects/$PROJECT_ID/resources \
  -H "Authorization: Bearer $DEKKA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "queue",
    "name": "jobs",
    "spec": {
      "visibility_timeout_seconds": 300,
      "retention_seconds": 604800,
      "max_message_bytes": 65536,
      "dead_letter_after": 5
    }
  }'
```

## What do the queue settings mean?

The visibility timeout is how long a received message stays hidden from other consumers before it can be received again, so make it longer than your slowest job takes. A message that's still in the queue when its retention ends is deleted unread, and with dead letters on, a message received that many times moves to the queue's dead-letter queue.

| In the dashboard | `spec` field | Allowed | Default |
| --- | --- | --- | --- |
| Visibility timeout | `visibility_timeout_seconds` | 0 to 43200 seconds (12 hours) | 30 |
| Keep messages for | `retention_seconds` | 60 to 1209600 seconds (14 days) | 345600 (four days) |
| Not shown | `max_message_bytes` | 1024 to 262144 bytes | 262144 |
| Move to dead letters after | `dead_letter_after` | 1 to 1000 receives, or `null` to keep every message | `null` |

The dashboard offers visibility timeouts from 30 seconds to 12 hours and retention of 1, 4, 7 or 14 days, and the API takes any value in range. The dashboard has no settings for a queue once it exists, so change one with `PATCH /v1/resources/{id}` and the whole `spec`, because any field you leave out goes back to its default.

## Connect a service

Drag from a web service, worker or cron job to the queue. Each connection gets its own token, and the service receives it in a secret `QUEUE_URL` and restarts to pick it up.

```text
https://<token>@queues.<region>.dekka.cloud/queues/<slug>
```

The token is the URL's user info, so `QUEUE_URL` is the only variable a client needs. The path ends in the queue's slug, which is its name followed by four random characters, such as `jobs-k3x9`.

## How do I send and receive messages?

There's no message API yet. `QUEUE_URL` is the address and token your code will use, and Dekka will describe the protocol for sending and receiving messages once queues leave simulation. If a job needs a queue today, a [Redis](/docs/redis) database that refuses writes when full can hold one.

## How many queues can I have?

| Plan | Queues |
| --- | --- |
| Free | 1 |
| Starter | 5 |
| Growth | 20 |

Every queue that isn't deleted counts, including the copy a forked environment such as a pull request preview makes, and creating one past the limit answers 403 `entitlement_exceeded`. Messages and storage aren't billed yet.

## Delete a queue

Disconnect every service, then choose **Delete queue** from the queue's menu and type its name. Deleting a queue deletes every message in it, and queues aren't backed up. The API deletes with `DELETE /v1/resources/{id}?confirm=<name>`, answers 422 `confirmation_required` without the name and 409 `resource_has_connections` while a service is still connected.
