queues について
永続トピックと独立したコンシューマーを必要とする開発者向けに、Vercel Queues によるバックグラウンドメッセージ処理を案内するスキルです。発行、プッシュまたはポーリングでの受信、リトライ、保持期間に加え、Workflows を選ぶ場面も説明します。
主な機能
- 01永続トピックとコンシューマーグループ
- 02プッシュとポーリングの受信モード
- 03少なくとも1回の配信とリトライ設定
- 04遅延配信、保持期間、冪等性オプション
- 05JavaScript と Python の SDK ガイド
- 06Queues と Workflows の選定指針
活用シーン
- 01バックグラウンドジョブの一時保管と後続処理
- 02複数の独立したコンシューマーグループへのイベント配信
- 03Vercel Functions または外部ワーカーでのメッセージ受信
- 04新しいコンシューマーグループによる保持中メッセージの再生
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ vercel/ vercel-plugin --skill queuesインストール後、Claude Code で/queuesを入力して読み込まれたか確認します。
同梱ファイル.vercel.approvers
詳細
Vercel Queues
Vercel Queues に関する専門知識を持っています。Vercel 上のバックグラウンド処理とエージェントのイベントを支える、耐久性のあるメッセージトピックです。
概要
Vercel Queues(パブリックベータ)では、耐久性のある追記専用トピックを利用できます。プロデューサーが JSON メッセージを発行すると、購読しているすべてのコンシューマーグループに、少なくとも 1 回の配信と自動再試行が行われます。新しいコンシューマーグループは後から参加し、有効期限が切れていない履歴を再生できます。Queues は Vercel Workflows の基盤となるプリミティブです。発行、消費、ルーティングを制御する必要がある場合は、Queues を直接使用してください。
- トピック:最初の発行時に作成される、名前付きの耐久性のあるメッセージログ
- コンシューマーグループ:トピック上のすべてのメッセージを受信する独立したサブスクライバー
- 配信:少なくとも 1 回。ハンドラーは冪等である必要があります
- 保持期間:デフォルトは 24 時間、最長 7 日間。配信は保持期間まで遅延させられます
- モード:プッシュ(Vercel が関数を呼び出します)またはポーリング(任意の環境から独自のワーカーがメッセージを取得します)
Queues と Workflows の選択
| 必要なこと | 使用するもの | 理由 |
|---|---|---|
| 実行結果を待たないバックグラウンドジョブ、ファンアウト、バッファリング | Queues | 直接の発行と消費、独立したコンシューマーグループ |
| スリープ、フック、または人による承認を含む複数ステップのロジック | Workflows(⤳ skill: workflow) | Queues 上に構築された、耐久性のあるステップと再生 |
| cron による定期的な呼び出し | Cron Jobs(⤳ skill: vercel-functions) | 時間ベースのトリガーであり、メッセージベースではありません |
クイックスタート(Next.js App Router)
SDK をインストールします。
npm install @vercel/queue
任意のルート、Server Action、または関数から発行します。
// 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 });
}
プッシュモードのハンドラーで消費します。ハンドラーが戻るとメッセージは確認応答され、例外をスローすると再試行されます。
// 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 がトピックをその関数にルーティングします。
{
"functions": {
"app/api/queues/process-order/route.ts": {
"experimentalTriggers": [{ "type": "queue/v2beta", "topic": "orders" }]
}
}
}
ローカル開発の前に vercel link と vercel env pull を実行し、SDK が認証できるようにします。
送信オプション
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 min(retention, 24 hours) are dropped
headers: { 'x-trace-id': 'abc-123' },
});
デフォルト値、固定リージョン、または複数のクライアントが必要な場合は、QueueClient を作成します。
// lib/queue.ts
import { QueueClient } from '@vercel/queue';
const queue = new QueueClient({ region: 'sfo1' });
export const { send, handleCallback } = queue;
コンシューマーのオプションと再試行
handleCallback(handler, options) では、次のオプションを指定できます。
| オプション | デフォルト | 説明 |
|---|---|---|
visibilityTimeoutSeconds | 300 | メッセージが処理中の状態で維持される時間です。ハンドラーの実行中、SDK がリースを延長します |
retry | トリガーの retryAfterSeconds(60s) | (error, metadata) => { afterSeconds } | { acknowledge: true } | undefined |
配信回数のしきい値を超えたら確認応答することで、有害なメッセージを処理します。
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) を受け取ります。
その他のランタイムとフレームワーク
- Python:
vercel-queueは同じトピックモデルで発行と消費を行います。FastAPI、Flask、Django のアプリで使用できます。Celery と Dramatiq の連携については、Python バックエンドフレームワークのドキュメントを参照してください。 - Nitro / Nuxt:
nitro.config.tsでvercel.queues.triggersを宣言し、vercel:queueランタイムフックでメッセージを処理します。@vercel/queueのsendは任意のサーバールートで動作します。 - ポーリングモード:プッシュ配信が Vercel Function に適さない場合は、任意の環境で独自のワーカーからメッセージを取得します。Vercel 上では、デーモンとして常時稼働するポーリングモードのコンシューマーを実行します(
⤳ skill: daemons)。 - ペイロード:デフォルトは JSON です。
QueueClientの構築時に、バイナリにはBufferTransportを、大きな本文にはStreamTransportを使用します。
エラー
@vercel/queue は型付きエラーとして、UnauthorizedError、BadRequestError、MessageNotFoundError、QueueEmptyError をエクスポートします。重複する冪等性キーを指定しても例外はスローされず、重複分は通知なしで破棄されます。
よくある落とし穴
- トリガーの登録漏れ:
experimentalTriggersエントリーのないhandleCallbackルートは、メッセージを受信できません。すべてのコンシューマーをvercel.json/vercel.tsに登録してください。 - 冪等性のないハンドラー:メッセージは少なくとも 1 回配信されます。副作用のキーには
metadata.messageIdまたは独自のidempotencyKeyを使用してください。 - 再試行の無限ループ:有害なメッセージを確認応答する
retryポリシー、またはトリガーのmaxDeliveries上限がない場合、恒久的に失敗するメッセージは期限切れになるまで再配信されます。 - 複数ステップのロジックに Queues を使用する:各ステップの間にスリープ、フック、承認が必要な場合は、手動でトピックを連鎖させるのではなく、Workflows を使用してください。
- 認証情報なしでのローカル開発:先に
vercel linkとvercel env pullを実行してください。実行しない場合、send()はFailed to get OIDC token for local developmentをスローします。
参考資料
- 📖 ドキュメント:https://vercel.com/docs/queues
- 📖 JavaScript SDK:https://vercel.com/docs/queues/sdk
- 📖 Python SDK:https://vercel.com/docs/queues/python-sdk
- 📖 ポーリングモード:https://vercel.com/docs/queues/poll-mode
- 📖 料金と制限:https://vercel.com/docs/queues/pricing