Vercel Queues retry can resubmit a paid Sume job
A Vercel Queues consumer that times out is redelivered, and maxDeliveries is unlimited by default. Reuse one Idempotency-Key per message so Sume bills once.

Yes: a Vercel Queues consumer that submits a Sume job and then times out will be redelivered, and a second submit without the same Idempotency-Key can create a second paid job. Vercel counts a delivery as failed when the message is not acknowledged before the lease runs out, and maxDeliveries defaults to unlimited.
Vercel behavior is from its Queues concepts page, read 2026-09-30. Sume behavior is from Jobs and results and Errors and credits.
When does Vercel redeliver?
A delivery fails if the handler threw, the function crashed or timed out, or the function could not be reached. A delivery that fails by timing out is billed for the function's full maxDuration. The default retryAfterSeconds is 60 seconds, and there is no built-in dead-letter queue. Returning { acknowledge: true } from the SDK's retry callback stops redelivery.
Why is that dangerous with a Sume submit?
A client-side timeout does not cancel a Sume job. It keeps running and still bills. The docs say not to resubmit the original paid request because a local timeout fired, and not to retry unsafe submits without an Idempotency-Key. Retrying the submit itself is fine if you reuse the same key, so the retry returns the original job.
| Situation | What to do |
|---|---|
| Redelivered message, same job intent | Send the same Idempotency-Key |
| Key reused with a different payload | Sume returns 409 idempotency_conflict; reuse keys only for exact retries |
| Handler timed out while waiting | Store the job id and poll status_url; do not resubmit |
| Message keeps failing | Cap maxDeliveries and handle the last attempt yourself |
How do I derive the key?
Build it from something stable per message, such as your own message or order id, so every redelivery sends the identical value. Do not generate a random key inside the handler: each redelivery would then look like new work. More background in idempotency keys for AI video APIs.
What should I cap?
Set maxDeliveries to a small number, since the default is unlimited and timeouts are billed at full maxDuration. Better, make the consumer short: submit with mode: "async", save the job id, acknowledge, and let a later step poll or receive the webhook.
Sources
Related posts
More in Developers
- Vercel rewrite to an external API times out at 120 seconds
Vercel proxied rewrites to an external destination time out at 120 seconds with ROUTER_EXTERNAL_TARGET_ERROR. A Sume async submit returns at once.
- Video 1.0 4k resolution error: only 720p and 1080p on that URL
Video 1.0 accepts 720p (default) and 1080p from its legacy vocabulary and rejects 4k. For 4K send a sume/auto request to POST /v1/videos instead.
- Video 1.0 bitrate_mode: still in the shape, rejected by Auto
bitrate_mode is retained in Video 1.0's legacy request shape but Auto rejects it. Omit it, and note that Gemini Omni Flash 1.1 has no bitrate_mode either.
- Video 1.0 duration vs duration_seconds: what if they differ?
Video 1.0 accepts duration and its alias duration_seconds. If you send both they must agree; the value is checked against the Auto serving family.
Written by Sume