queues

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Vercel 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

NeedUseWhy
Fire-and-forget background job, fan-out, bufferingQueuesDirect publish/consume, independent consumer groups
Multi-step logic with sleep, hooks, or human approvalWorkflows (
⤳ skill: workflow
)
Durable steps and replay built on top of Queues
Scheduled invocation on a cronCron Jobs (
⤳ skill: vercel-functions
)
Time-based trigger, not message-based
需求使用原因
即发即忘(fire-and-forget)的后台任务、扇出、缓冲Queues直接发布和消费,支持独立消费者组
包含 sleep、hooks 或人工审批的多步骤逻辑Workflows(
⤳ skill: workflow
)
构建在 Queues 之上的持久步骤和重放机制
通过 cron 定时调用Cron Jobs(
⤳ skill: vercel-functions
)
基于时间而非消息的触发器

Quickstart (Next.js App Router)

快速入门(Next.js App Router)

Install the SDK:
bash
npm install @vercel/queue
Publish 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
vercel.json
(or
vercel.ts
) so Vercel routes the topic to that function:
json
{
  "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.
安装 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.json
(或
vercel.ts
)中注册消费者,以便 Vercel 将该 topic 路由到对应函数:
json
{
  "functions": {
    "app/api/queues/process-order/route.ts": {
      "experimentalTriggers": [{ "type": "queue/v2beta", "topic": "orders" }]
    }
  }
}
本地开发前运行
vercel link
和
vercel env pull
,以便 SDK 完成身份验证。

Send 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
QueueClient
when you need defaults, a fixed region, or multiple clients:
ts
// 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 或多个客户端时,创建
QueueClient
:
ts
// 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:
OptionDefaultNotes
visibilityTimeoutSeconds
300How 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:
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) };
  },
});
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)
.
handleCallback(handler, options)
接受以下选项:
选项默认值说明
visibilityTimeoutSeconds
300消息处于处理中状态的时长;处理器运行期间,SDK 会自动延长租约(lease)
retry
内置退避
(error, metadata) => { afterSeconds } | { acknowledge: true } | undefined
处理毒消息(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) };
  },
});
metadata
包含
messageId
、
deliveryCount
、
createdAt
、
expiresAt
、
topicName
、
consumerGroup
和
region
。
对于 Express、Connect 或 Next.js Pages Router 处理器,请使用
QueueClient
实例的
queue.handleNodeCallback(async (message, metadata) => ...)
,其接收
(req, res)
。

Other Runtimes and Frameworks

其他运行时与框架

  • Python:
    vercel-queue
    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.
  • Nitro / Nuxt: declare
    vercel.queues.triggers
    in
    nitro.config.ts
    and handle messages with the
    vercel:queue
    runtime hook;
    send
    from
    @vercel/queue
    works 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
    BufferTransport
    for binary or
    StreamTransport
    for large bodies when constructing a
    QueueClient
    .
  • Python:
    vercel-queue
    使用相同的 topic 模型发布和消费消息,FastAPI、Flask 和 Django 应用均可使用;Celery 和 Dramatiq 集成记录在 Python 后端框架文档下。
  • Nitro / Nuxt:在
    nitro.config.ts
    中声明
    vercel.queues.triggers
    ,并通过
    vercel:queue
    runtime hook 处理消息;从
    @vercel/queue
    导入的
    send
    可在任何服务端路由中使用。
  • Poll mode:如果不适合将消息 push 到 Vercel Function,可从任意环境使用自己的 workers 拉取消息。
  • Payloads:默认使用 JSON;创建
    QueueClient
    时,可使用
    BufferTransport
    处理二进制数据,或使用
    StreamTransport
    处理大型正文。

Errors

错误

@vercel/queue
exports typed errors:
UnauthorizedError
,
BadRequestError
,
DuplicateMessageError
(idempotency-key collision),
MessageNotFoundError
, and
QueueEmptyError
.
@vercel/queue
导出以下类型化错误:
UnauthorizedError
、
BadRequestError
、
DuplicateMessageError
(幂等键冲突)、
MessageNotFoundError
和
QueueEmptyError
。

Common Pitfalls

常见问题

  1. Missing trigger: a
    handleCallback
    route with no
    experimentalTriggers
    entry never receives messages. Register every consumer in
    vercel.json
    /
    vercel.ts
    .
  2. Non-idempotent handlers: delivery is at-least-once. Key side effects on
    metadata.messageId
    or your own
    idempotencyKey
    .
  3. Retrying forever: without a
    retry
    policy that acknowledges poison messages, a permanently failing message is redelivered until it expires.
  4. Using Queues for multi-step logic: if you need sleep, hooks, or approvals between steps, use Workflows instead of chaining topics by hand.
  5. Local dev without credentials: run
    vercel link
    and
    vercel env pull
    first; otherwise
    send()
    fails with
    UnauthorizedError
    .
  1. 缺少 trigger:没有
    experimentalTriggers
    条目的
    handleCallback
    路由永远不会收到消息。必须在
    vercel.json
    /
    vercel.ts
    中注册每个消费者。
  2. 非幂等处理器:投递语义为至少一次。让副作用操作以
    metadata.messageId
    或你自己的
    idempotencyKey
    为键。
  3. 无限重试:如果没有用于确认毒消息的
    retry
    策略,永久失败的消息会持续重新投递,直至过期。
  4. 将 Queues 用于多步骤逻辑:如果需要在步骤之间执行 sleep、使用 hooks 或进行审批,请使用 Workflows,而不是手动串联 topics。
  5. 本地开发缺少凭据:先运行
    vercel link
    和
    vercel env pull
    ;否则
    send()
    将因
    UnauthorizedError
    而失败。

References

参考资料