Concepts
Queues concepts
Vercel Queues is a durable event streaming system for asynchronous workloads. You publish messages to topics, and consumer groups process those messages independently with at-least-once delivery, retries, and visibility timeouts.
Queues is useful when you need to decouple request handling from background processing, absorb traffic spikes, and keep work reliable across function failures or deployment changes.
Vercel Queues overview
Vercel Queues is Vercel's managed queueing system for durable, asynchronous message processing. It acts as a reliability layer between producers and consumers:
- Producers publish messages to a topic.
- Consumer groups read and process those messages independently.
- Messages persist until they are acknowledged or expire.
- Failed processing attempts are retried automatically.
- Delivery is at-least-once, so consumers should be idempotent.
Vercel Queues vs Workflows
Vercel Queues and Vercel Workflows solve related but different problems:
Vercel Queues
Primary abstraction
Best for
Execution model
Topics, messages, and consumer groups
Event delivery, fan-out consumers, and routing control
Durable steps and workflow runs
Step-driven orchestration with built-in state between steps
Failure handling
Use this when
Retries, visibility timeout, and idempotent consumers
You need low-level control over publish/consume behavior
Retries at step boundaries with workflow-aware recovery
You need high-level orchestration and durable business flows
Use Queues when you want direct control over event ingestion and delivery. Use Workflow when you want a higher-level programming model for long-running business processes.
How Vercel Queues works
At a high level, Vercel Queues follows a publish, lease, acknowledge, and retry flow:
- A producer publishes a message to a topic.
- The topic makes that message available to each consumer group.
- A consumer in a group receives the message under a visibility timeout lease.
- If processing succeeds, the consumer acknowledges the message and removes it from that group.
- If processing fails or times out, the lease expires and the message is retried.
Messages remain durable throughout this lifecycle and are removed when acknowledged or when their retention period expires.
Topics and consumer groups
A topic is a durable, append-only log of messages. Producers publish messages to a topic, and the topic fans them out to all subscribed consumer groups. Messages are retained until they expire, regardless of whether any consumer has processed them. Retention is configurable per-message from 60 seconds to 7 days, defaulting to 24 hours.
A consumer group is an independent subscriber to a topic. Each group tracks its own position in the log and processes messages at its own pace. Because groups are fully isolated, a slow or failing consumer in one group has no effect on any other.
vercel.json. Python projects declare subscriber entrypoints in
pyproject.toml.
Vercel manages partitioning and scaling for you. You don't need to pre-configure partition counts, manage rebalancing, or provision throughput capacity. Queues scale with your traffic automatically.
Durability
When Vercel Queues accepts a message, it guarantees the message can be consumed. Every message is synchronously written to three separate availability zones before the publish call returns. This means your message is fully replicated before your producer receives confirmation. Even if an entire availability zone goes down, the message is safe.
After replication, the publish acknowledgment and consumer notification happen simultaneously. This means a consumer may receive and begin processing a message before the producer's publish call returns, depending on network latency.
Once Vercel accepts a message, it retries delivery until the message is successfully processed or expires. Vercel only removes a message from the topic after your consumer acknowledges it. If your consumer crashes, a deployment rolls out, or the function times out, Vercel redelivers the message automatically.
Vercel Queues provides at-least-once delivery semantics. Every accepted message is delivered to each consumer group at least one time. In most cases, a message is delivered exactly once, but there are edge cases where a message may be delivered more than once:
- Consumer timeouts: If your function processes a message but doesn't acknowledge it before the visibility timeout expires, Vercel assumes the delivery failed and redelivers the message.
- Infrastructure events: During rare events like availability zone failovers, a message that was already delivered may be redelivered.
Design your consumers to be idempotent, meaning they produce the same result whether they process a message once or multiple times. Common strategies include using a unique message ID to deduplicate, or making operations naturally idempotent (like setting a value rather than incrementing it).
When a message is delivered to a consumer, it becomes temporarily invisible to other consumers in the same group. This is the visibility timeout. During this window, the message is "in flight" and won't be delivered again.
If your consumer processes the message and acknowledges it before the timeout expires, the message is removed. If the consumer crashes, times out, or fails to acknowledge, the visibility timeout expires and the message becomes available for redelivery.
This is how Vercel Queues handles failures without manual intervention. You don't need to build retry infrastructure or monitor for stuck messages. If a Vercel Function crashes mid-processing or hits its execution time limit, the message automatically returns to the queue and gets delivered to the next available consumer.
The default visibility timeout is 60 seconds. You can configure it per receive request from 0 to 3,600 seconds (60 minutes). Setting it to 0 peeks at the message without leasing it. If your consumer needs more time mid-processing, you can extend the lease using the ExtendLease API.
Message lifecycle
A message moves through several states from the time it's published to when it's processed or expires:
- SendMessage writes the message. If a delay is configured, the message enters a pending state.
- Once the delay expires (or immediately if no delay), the message becomes visible to consumers.
- ReceiveMessages claims the message and starts a lease ( visibility timeout). The message is now in-flight.
- AcknowledgeMessage permanently removes the message from the consumer group.
- ExtendLease resets the visibility timeout if your consumer needs more processing time.
- If the lease expires without acknowledgment, the message becomes visible again with an incremented delivery count.
- Messages are permanently deleted when their retention period (TTL) expires, regardless of processing state. Once a message expires, it cannot be consumed.
See the API reference for details on each operation.
Regions and data residency
Vercel Queues is available in all 20 Vercel regions. When you create a queue, you select a region, and your message data is persisted in that region. The three-zone replication described in Durability happens across availability zones within your selected region.
Choose a region close to your producers and consumers to minimize latency. If you need queues in multiple regions, create separate queues in each region. See the regions documentation for the full list of available regions.
Vercel writes queue data to the region you select. During a regional outage, Vercel may temporarily store messages in a neighboring region and relocate them once the target region recovers. This ensures ingestion continues even when a region is unavailable.
Deployments and versioning
On Vercel, topics are partitioned by deployment ID by default. In push mode, Vercel delivers messages back to the same deployment that published them.
This design means you don't have to worry about message compatibility across deployments. When you change a message schema or update your consumer logic, the new deployment produces and consumes its own messages. There's no risk of a new deployment consuming messages published by an older version with a different format.
This is useful during rollouts: both the current and previous deployments can have active queues processing their own messages independently until the old deployment drains.
poll mode, you can reference the deployment ID as an opaque version identifier to partition your consumers manually, or omit it entirely and handle versioning at the application level.
Stopping deliveries to a deployment
Because messages stay pinned to the deployment that published them, promoting or rolling back to a different deployment does not stop deliveries to the old one. Its consumer functions keep being invoked, and keep being retried, until every message it published is acknowledged or expires. A deployment that was in production for a few minutes can therefore stay busy for up to the message retention period (24 hours by default) if its messages keep failing.
To stop a deployment's consumers from running, delete the deployment. Vercel stops invoking its functions immediately. Pending messages stay in the queue until they expire, but no compute is used for them.
Two settings bound how much compute resources a failing deployment can consume:
- Cap retries. Set maxDeliveries on the trigger so a message that keeps failing is dropped after a bounded number of deliveries.
- Acknowledge bad messages. As an alternative to the above, you can return { acknowledge: true } from the SDK's retry callback based on any checks you want to perform, which will stop the message from being redelivered.
To see which deployments are consuming compute, open the Observability Query tab with function duration grouped by deployment. A deployment that is no longer current but still accounts for a large share of GB-hours is a deployment with failing consumers.
Delivery
By default, Vercel delivers messages to your Vercel Functions using push mode. When a message is published to a topic, Vercel invokes your consumer function automatically with fluid compute. You define a consumer function, and Vercel calls it for each message (or batch of messages) as they become available.
import { handleCallback } from'@/lib/queue';
exportconstPOST=handleCallback(async (message, metadata) => {
awaitprocessOrder(message);
});
For consumers running outside of Vercel, or advanced on-Vercel setups that need more control, Vercel Queues also supports poll mode. Both modes provide the same delivery guarantees and can be used together within the same queue.
Queue consumer functions on Vercel are not accessible from the outside world. JavaScript and TypeScript projects configure a consumer by adding a queue/v2beta trigger to vercel.json:
{
"functions": {
{
"experimentalTriggers": [
"app/api/queues/process-order/route.ts": {
"type":"queue/v2beta",
"topic":"orders",
}
]
"retryAfterSeconds":60,
}
"initialDelaySeconds":0,
"maxDeliveries":20
Option
Time before a failed message is retried
retryAfterSeconds
Topic name to consume. Supports wildcards (e.g., order-*)
Type
Default
Trigger type. Use queue/v2beta
string
maxDeliveries
Delay before the consumer starts processing after deploy
string
Description
60 seconds
number
initialDelaySeconds
Deliveries after which a message is no longer retried. See Retries
number
number
Zero seconds
Unlimited
Multiple route files with the same topic create separate consumer groups, each receiving a copy of every message.
With this configuration, the function is completely air-gapped from the internet. It has no public URL and can only be invoked by Vercel's internal queue infrastructure.
This means you don't need to add authentication or authorization logic to your consumer functions. Unauthorized requests can never reach them. Only messages delivered through Vercel Queues can trigger execution.
In poll mode, security works differently because your application initiates the connection. Your code authenticates with the Vercel API using standard OIDC tokens when polling for messages, the same way you authenticate with any other Vercel API.
You can delay a message's visibility by setting a delay when publishing. The message is accepted and stored immediately, but consumers won't see it until the delay expires. Delays can be set from 0 seconds up to 7 days, but cannot exceed the message's TTL.
This is useful for scheduling future work, such as sending a reminder email in 30 minutes or retrying an external API call after a cooldown period.
If you need to schedule work further into the future than the 7-day maximum delay, consider these approaches:
- Daisy-chain messages: Publish a message with the maximum delay, then have your consumer republish another delayed message until you reach the target time.
- Use Vercel Workflows: Vercel Workflows supports sleep() for arbitrarily long durations with built-in durability. This is often simpler than managing chained messages yourself.
You can include an idempotency key when publishing a message to have Vercel deduplicate it for you. Vercel handles deduplication out-of-band after the publish call returns, so the SendMessage response itself always succeeds. The duplicate is silently dropped, and the original message continues to be delivered with at-least-once semantics.
In practice, this means:
- Push and poll mode consumers never receive the duplicate message. It's filtered out before delivery. The original message is unaffected.
- ReceiveMessageById returns a 409 response with the originalMessageId if you try to receive a duplicate by its ID. This lets you follow the redirect to the original message.
The deduplication window lasts for the entire lifetime of the original message (up to its TTL). As long as the original message hasn't expired, any republish with the same idempotency key is deduplicated. This means you're protected from duplicate messages for the full retention period, whether that's 60 seconds or 7 days.
This is useful when your producer might retry a publish (for example, after a network timeout) and you need to guarantee exactly-once publishing.
In push mode, you can set a maximum concurrency per consumer group. This limits how many messages can be in-flight simultaneously for that group. If the limit is reached, Vercel holds back delivery until an in-flight message is acknowledged or its lease expires.
You can reach our customer support team by emailing info@yourcompany.example.com, calling +1 555-555-5556, or using the live chat on our website. Our dedicated team is available 24/7 to assist with any inquiries or issues.
We’re committed to providing prompt and effective solutions to ensure your satisfaction.
We offer a 30-day return policy for all products. Items must be in their original condition, unused, and include the receipt or proof of purchase. Refunds are processed within 5-7 business days of receiving the returned item.
Every delivery to a push consumer is a function invocation. If a delivery fails by timing out, it is billed for the function's full maxDuration at its configured memory. To prevent runaway costs for misconfigured deployments, set up a retry depth alert, and stop it as described in Stopping deliveries to a deployment.
Vercel Queues doesn't have a built-in dead-letter queue. Instead, you handle poisoned messages at the application level using the SDK's retry handler.
Because messages with no delivery attempts are always prioritized over retried messages, a poisoned message naturally falls to lower priority. Your consumer keeps progressing through new messages while the failing message retries in the background. Even with max concurrency set to 1, a poisoned message can't block your consumer.
Use the retry callback to control backoff timing and acknowledge poisoned messages to stop retrying them:
async (message, metadata) => {
import { handleCallback } from'@/lib/queue';
See the JS SDK reference for the full retry API.
Ordering
Vercel Queues delivers messages in approximate write order. Messages are generally delivered in the order they were published, but strict ordering is not guaranteed:
- Retried messages have lower priority than new messages. If a message fails and is retried, new messages published in the meantime may be delivered first.
- No FIFO guarantee. Even with a single consumer and max concurrency set to 1, message order is not strictly first-in-first-out.
If your workload requires strict ordering, design your consumers to handle messages in any order, or include sequence numbers in your message payloads to reorder on the consumer side.
Queues with services
Queue consumers work the same inside a service. You add a queue/v2beta trigger to a function to make it a consumer, and several services can consume the same topic at once:
{
"root":"orders",
}
"orders": {
"functions": {
"app/api/queues/fulfill-order/route.ts": {
"experimentalTriggers": [{ "type":"queue/v2beta","topic":"orders" }]
}
},
"services": {
"analytics": {
"root":"analytics",
"functions": {
}
}
"app/api/queues/track-order/route.ts": {
}
}
}
Topics are project-scoped
Consumer groups across services
Last updated September 10, 2026
Previous
Topics belong to the project and deployment, not to an individual service. Every service in the deployment publishes to and consumes from the same set of topics.
Cross-link map: Queues concepts (/docs/queues/concepts)From the Vercel docs graph (built 2026-09-21T05:26:59.511Z), spanning vercel.com docs + KB, nextjs.org, ai-sdk.dev, and other Vercel documentation sites. Full graph as JSON: https://vercel.com/docs/graph.jsonSemantically closest pagesVercel Queues — Publish agent events and background work to durable topics with independent consumers, automatic retries, and at-least-oPoll Mode — Consume messages from Vercel Queues by polling on your own schedule, from any environment.Vercel Queues: Python SDK Reference — Publish and consume messages with the Vercel Queues Python SDK.API Reference — HTTP API reference for Vercel Queues. Publish, consume, acknowledge, and manage messages.Publish and subscribe to realtime data on Vercel — Learn how to publish and subscribe to realtime data on Vercel with WebSockets, SSE, Redis, and Queues, and when a manageThis page links to (12)Fluid compute — Learn about fluid compute, an execution model for Vercel Functions that provides a more flexible and efficient way to ruVercel Functions — Build API routes, webhooks, and agent request handlers with Vercel Functions, then test and debug them with Vercel CLI.API Reference — HTTP API reference for Vercel Queues. Publish, consume, acknowledge, and manage messages.Queues Observability — Monitor queue throughput, message age, retries, and consumer performance to optimize your queue-based workflows.Poll Mode — Consume messages from Vercel Queues by polling on your own schedule, from any environment.Pricing and Limits — Understand how Vercel Queues billing works, what's included, and which service limits apply.Vercel Queues: Python SDK Reference — Publish and consume messages with the Vercel Queues Python SDK.Vercel Queues: JS SDK Reference — Publish and consume messages with the Vercel Queues SDK for JavaScript and TypeScript.Global network and regions — View the list of regions supported by Vercel's CDN and learn about our global infrastructure.Services — Deploy multiple backends and frontends within a single Vercel project using services.Service bindings — Call one service from another using caller-declared service bindings.Vercel Workflows — Build agents and applications that retry failed steps, wait for external events, and resume across crashes and deploymenPages that link here (9)By site: vercel-kb (2) · workflow (1) · vercel-docs (6)From vercel-kbHow to run background jobs in Next.js — Learn the durable way to run background jobs in Next.js on Vercel with the Workflow SDK, and when to reach for Queues orPublish and subscribe to realtime data on Vercel — Learn how to publish and subscribe to realtime data on Vercel with WebSockets, SSE, Redis, and Queues, and when a manageFrom workflowFramework Integrations — Build a custom framework integration using the Workflow SDK compiler and runtime.From vercel-docsDeploy Dramatiq workers on Vercel — Deploy Dramatiq workers on Vercel. Learn how Dramatiq actors use Vercel Queues and Vercel Functions to process backgrounVercel Queues — Publish agent events and background work to durable topics with independent consumers, automatic retries, and at-least-oAPI Reference — HTTP API reference for Vercel Queues. Publish, consume, acknowledge, and manage messages.Queues Observability — Monitor queue throughput, message age, retries, and consumer performance to optimize your queue-based workflows.Poll Mode — Consume messages from Vercel Queues by polling on your own schedule, from any environment.Services — Deploy multiple backends and frontends within a single Vercel project using services.
Quickstart
In push mode, triggers in different services have independent consumer groups, so each consumer in a service receives its own copy of every message. In poll mode, you need to manage consumer groups manually to avoid collisions across services.
Was this helpful?
A queue consumer is never reachable from the internet, the same as in a single-application project. Adding a top-level rewrite to expose a service does not expose its consumers, because the rewrite only routes public traffic while consumers are invoked by Vercel's internal queue infrastructure. A consumer is also unreachable over a service binding: bindings let other services call the service's exposed routes, but a queue consumer can only be triggered by Vercel Queues.