queues
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseVercel Queues
Vercel Queues
You are an expert in Vercel Queues, the durable message topics that power background work and agent events on Vercel.
你是一名 Vercel Queues 专家。Vercel Queues 是为 Vercel 上的后台工作和 Agent 事件提供支持的持久消息主题。
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)
Vercel Queues(公共测试版)提供持久、append-only 的主题。生产者发布 JSON 消息,每个已订阅的消费者组都会收到主题中的每条消息,投递语义为至少一次,并支持自动重试。新的消费者组可以稍后加入,并重播尚未过期的历史消息。Queues 是 Vercel Workflows 的基础原语;当你需要控制发布、消费和路由时,应直接使用 Queues。
- Topic:具名的持久消息日志,在首次发布时创建
- Consumer group:独立订阅者,会收到主题中的每条消息
- Delivery:至少一次;处理器必须具备幂等性
- Retention:默认保留 24 小时,最长可达 7 天;投递延迟最长可达到保留期上限
- Modes:push(Vercel 调用你的函数)或 poll(你自己的 workers 从任意环境拉取消息)
Choose Queues or Workflows
选择 Queues 还是 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 ( | Durable steps and replay built on top of Queues |
| Scheduled invocation on a cron | Cron Jobs ( | Time-based trigger, not message-based |
| 需求 | 使用 | 原因 |
|---|---|---|
| 即发即忘(fire-and-forget)的后台任务、扇出、缓冲 | Queues | 直接发布和消费,支持独立消费者组 |
| 包含 sleep、hooks 或人工审批的多步骤逻辑 | Workflows( | 构建在 Queues 之上的持久步骤和重放机制 |
| 通过 cron 定时调用 | Cron Jobs( | 基于时间而非消息的触发器 |
Quickstart (Next.js App Router)
快速入门(Next.js App Router)
Install the SDK:
bash
npm install @vercel/queuePublish from any route, Server Action, or function:
ts
// 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:
ts
// 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 (or ) so Vercel routes the topic to that function:
vercel.jsonvercel.tsjson
{
"functions": {
"app/api/queues/process-order/route.ts": {
"experimentalTriggers": [{ "type": "queue/v2beta", "topic": "orders" }]
}
}
}Run and before local development so the SDK can authenticate.
vercel linkvercel env pull安装 SDK:
bash
npm install @vercel/queue从任意路由、Server Action 或函数发布消息:
ts
// 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 });
}使用 push 模式的处理器进行消费。处理器返回时消息会被确认;抛出异常时消息会重试:
ts
// 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);
});在 (或 )中注册消费者,以便 Vercel 将该 topic 路由到对应函数:
vercel.jsonvercel.tsjson
{
"functions": {
"app/api/queues/process-order/route.ts": {
"experimentalTriggers": [{ "type": "queue/v2beta", "topic": "orders" }]
}
}
}本地开发前运行 和 ,以便 SDK 完成身份验证。
vercel linkvercel env pullSend Options
发送选项
ts
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 when you need defaults, a fixed region, or multiple clients:
QueueClientts
// lib/queue.ts
import { QueueClient } from '@vercel/queue';
const queue = new QueueClient({ region: 'sfo1' });
export const { send, handleCallback } = queue;ts
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' },
});当你需要默认值、固定 region 或多个客户端时,创建 :
QueueClientts
// 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)| Option | Default | Notes |
|---|---|---|
| 300 | How long a message stays in flight; the SDK re-extends the lease while the handler runs |
| built-in backoff | |
Handle poison messages by acknowledging after a delivery-count threshold:
ts
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) };
},
});metadatamessageIddeliveryCountcreatedAtexpiresAttopicNameconsumerGroupregionFor Express, Connect, or Next.js Pages Router handlers use from a instance, which takes .
queue.handleNodeCallback(async (message, metadata) => ...)QueueClient(req, res)handleCallback(handler, options)| 选项 | 默认值 | 说明 |
|---|---|---|
| 300 | 消息处于处理中状态的时长;处理器运行期间,SDK 会自动延长租约(lease) |
| 内置退避 | |
处理毒消息(poison messages):达到投递次数阈值后确认消息。
ts
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) };
},
});metadatamessageIddeliveryCountcreatedAtexpiresAttopicNameconsumerGroupregion对于 Express、Connect 或 Next.js Pages Router 处理器,请使用 实例的 ,其接收 。
QueueClientqueue.handleNodeCallback(async (message, metadata) => ...)(req, res)Other Runtimes and Frameworks
其他运行时与框架
- Python: publishes 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.
vercel-queue - Nitro / Nuxt: declare in
vercel.queues.triggersand handle messages with thenitro.config.tsruntime hook;vercel:queuefromsendworks in any server route.@vercel/queue - 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 for binary or
BufferTransportfor large bodies when constructing aStreamTransport.QueueClient
- Python:使用相同的 topic 模型发布和消费消息,FastAPI、Flask 和 Django 应用均可使用;Celery 和 Dramatiq 集成记录在 Python 后端框架文档下。
vercel-queue - Nitro / Nuxt:在 中声明
nitro.config.ts,并通过vercel.queues.triggersruntime hook 处理消息;从vercel:queue导入的@vercel/queue可在任何服务端路由中使用。send - Poll mode:如果不适合将消息 push 到 Vercel Function,可从任意环境使用自己的 workers 拉取消息。
- Payloads:默认使用 JSON;创建 时,可使用
QueueClient处理二进制数据,或使用BufferTransport处理大型正文。StreamTransport
Errors
错误
@vercel/queueUnauthorizedErrorBadRequestErrorDuplicateMessageErrorMessageNotFoundErrorQueueEmptyError@vercel/queueUnauthorizedErrorBadRequestErrorDuplicateMessageErrorMessageNotFoundErrorQueueEmptyErrorCommon Pitfalls
常见问题
- Missing trigger: a route with no
handleCallbackentry never receives messages. Register every consumer inexperimentalTriggers/vercel.json.vercel.ts - Non-idempotent handlers: delivery is at-least-once. Key side effects on or your own
metadata.messageId.idempotencyKey - Retrying forever: without a policy that acknowledges poison messages, a permanently failing message is redelivered until it expires.
retry - 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 and
vercel linkfirst; otherwisevercel env pullfails withsend().UnauthorizedError
- 缺少 trigger:没有 条目的
experimentalTriggers路由永远不会收到消息。必须在handleCallback/vercel.json中注册每个消费者。vercel.ts - 非幂等处理器:投递语义为至少一次。让副作用操作以 或你自己的
metadata.messageId为键。idempotencyKey - 无限重试:如果没有用于确认毒消息的 策略,永久失败的消息会持续重新投递,直至过期。
retry - 将 Queues 用于多步骤逻辑:如果需要在步骤之间执行 sleep、使用 hooks 或进行审批,请使用 Workflows,而不是手动串联 topics。
- 本地开发缺少凭据:先运行 和
vercel link;否则vercel env pull将因send()而失败。UnauthorizedError
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
- 📖 文档: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
- 📖 定价与限制:https://vercel.com/docs/queues/pricing