Vercel Queues
SkillCloud & infraGuides your agent through setting up Vercel queues that deliver tasks reliably with retries, delays, and fan-out.
Use Vercel Queues in Claude, ChatGPT or Ahel Desktop
Free. Sign in, add Vercel Queues and connect your AI. About a minute.
Also: Claude Code · Cursor · Codex
Then ask your AI: use the Vercel Queues skill
Details
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; ahel provides instructions and does not run this skill.
No other account needed.
Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
About this skill
Vercel Queues guidance, durable topics with at-least-once delivery, independent consumer groups, retries, delays, and idempotency keys via @vercel/queue (JS) or vercel-queue (Python). Use when deferring background work, buffering traffic, fanning out events, or choosing between Queues and Workflows
What this skill tells your AI
The instructions your AI receives, as published by vercel/vercel-plugin in skills/queues/SKILL.md and read by ahel’s review.
You are an expert in Vercel Queues, the durable message topics that power background work and agent events on Vercel.
What It Is
Vercel Queues (public beta) gives you durable, append-only topics. Producers publish JSON messages, and every subscribed consumer group receives every message with at-least-once delivery and automatic retries. New consumer groups can join later and replay non-expired history. Queues is the primitive under Vercel Workflows; use Queues directly when you need control over publishing, consumption, and routing.
- Topic: a named durable log of messages, created on first publish
- Consumer group: an independent subscriber that receives every message on a topic
- Delivery: at-least-once; handlers must be idempotent
- Retention: 24 hours by default, up to 7 days; delivery can be delayed up to the retention period
- Modes: push (Vercel invokes your function) or poll (your own workers pull messages from any environment)
Choose Queues or Workflows
| Need | Use | Why |
|---|---|---|
| Fire-and-forget background job, fan-out, buffering | Queues | Direct publish/consume, independent consumer groups |
| Multi-step logic with sleep, hooks, or human approval | Workflows (⤳ skill: workflow) | Durable steps and replay built on top of Queues |
| Scheduled invocation on a cron | Cron Jobs (⤳ skill: vercel-functions) | Time-based trigger, not message-based |
Quickstart (Next.js App Router)
Install the SDK:
npm install @vercel/queue
Publish from any route, Server Action, or function:
// app/api/orders/route.ts
import { send } from '@vercel/queue';
export async function POST(request: Request) {
const body = await request.json();
const { messageId } = await send('orders', { orderId: body.orderId, action: 'process' });
return Response.json({ messageId });
}
Consume with a push-mode handler. Messages are acknowledged when the handler returns and retried when it throws:
// app/api/queues/process-order/route.ts
import { handleCallback } from '@vercel/queue';
export const POST = handleCallback(async (message, metadata) => {
await processOrder(message);
console.log('processed', metadata.messageId, 'delivery', metadata.deliveryCount);
});
Register the consumer in vercel.json (or vercel.ts) so Vercel routes the topic to that function:
{
"functions": {
"app/api/queues/process-order/route.ts": {
"experimentalTriggers": [{ "type": "queue/v2beta", "topic": "orders" }]
}
}
}
Run vercel link and vercel env pull before local development so the SDK can authenticate.
Send Options
await send('orders', payload, {
region: 'sfo1', // target a specific region
retentionSeconds: 3600, // message TTL; min 60, max 604800 (7 days); default 24 hours
delaySeconds: 60, // delay first delivery; max 7 days, capped at the TTL
idempotencyKey: 'order-123', // duplicates within the retention window are dropped
headers: { 'x-trace-id': 'abc-123' },
});
Create a QueueClient when you need defaults, a fixed region, or multiple clients:
// lib/queue.ts
import { QueueClient } from '@vercel/queue';
const queue = new QueueClient({ region: 'sfo1' });
export const { send, handleCallback } = queue;
Consumer Options and Retries
handleCallback(handler, options) accepts:
| Option | Default | Notes |
|---|---|---|
visibilityTimeoutSeconds | 300 | How long a message stays in flight; the SDK re-extends the lease while the handler runs |
retry | built-in backoff | (error, metadata) => { afterSeconds } | { acknowledge: true } | undefined |
Handle poison messages by acknowledging after a delivery-count threshold:
export const POST = handleCallback(processOrder, {
retry: (error, metadata) => {
if (metadata.deliveryCount > 5) return { acknowledge: true }; // stop retrying
return { afterSeconds: Math.min(300, 2 ** metadata.deliveryCount * 5) };
},
});
metadata includes messageId, deliveryCount, createdAt, expiresAt, topicName, consumerGroup, and region.
For Express, Connect, or Next.js Pages Router handlers use queue.handleNodeCallback(async (message, metadata) => ...) from a QueueClient instance, which takes (req, res).
Other Runtimes and Frameworks
- Python:
vercel-queuepublishes and consumes with the same topic model, and FastAPI, Flask, and Django apps can use it; Celery and Dramatiq integrations are documented under the Python backend frameworks. - Nitro / Nuxt: declare
vercel.queues.triggersinnitro.config.tsand handle messages with thevercel:queueruntime hook;sendfrom@vercel/queueworks in any server route. - Poll mode: pull messages from your own workers in any environment when push delivery to a Vercel Function does not fit.
- Payloads: JSON by default; use
BufferTransportfor binary orStreamTransportfor large bodies when constructing aQueueClient.
Errors
@vercel/queue exports typed errors: UnauthorizedError, BadRequestError, DuplicateMessageError (idempotency-key collision), MessageNotFoundError, and QueueEmptyError.
Common Pitfalls
- Missing trigger: a
handleCallbackroute with noexperimentalTriggersentry never receives messages. Register every consumer invercel.json/vercel.ts. - Non-idempotent handlers: delivery is at-least-once. Key side effects on
metadata.messageIdor your ownidempotencyKey. - Retrying forever: without a
retrypolicy that acknowledges poison messages, a permanently failing message is redelivered until it expires. - Using Queues for multi-step logic: if you need sleep, hooks, or approvals between steps, use Workflows instead of chaining topics by hand.
- Local dev without credentials: run
vercel linkandvercel env pullfirst; otherwisesend()fails withUnauthorizedError.
References
- 📖 docs: https://vercel.com/docs/queues
- 📖 JS SDK: https://vercel.com/docs/queues/sdk
- 📖 Python SDK: https://vercel.com/docs/queues/python-sdk
- 📖 poll mode: https://vercel.com/docs/queues/poll-mode
- 📖 pricing and limits: https://vercel.com/docs/queues/pricing
Signals
- GitHub stars
- 295
- Forks
- 64
- Last commit
- Oct 2026
ahel review
K1binfo
installs-packages
Automated review, not a security audit. Ruleset v1+k2.
Advanced
- Item type
- skill
- Key
queues- Source
- github.com/vercel/vercel-plugin
github.com/vercel/vercel-plugin
Related picks
Skill · vercel-labs
The pick for Vercelvercel-deploy
Skill · davila7
The pick for Vercelclerk-nextjs-patterns
Skill · clerk
The pick for Next.jslogs-nextjs
Skill · posthog
The pick for Next.jsnodejs-backend-patterns
Skill · wshobson
The pick for Noderun-node-tests
Skill · hiroro-work
The pick for Node