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.

4 min readSume
All posts

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.

Retry rules from the Vercel and Sume docs, read 2026-09-30
SituationWhat to do
Redelivered message, same job intentSend the same Idempotency-Key
Key reused with a different payloadSume returns 409 idempotency_conflict; reuse keys only for exact retries
Handler timed out while waitingStore the job id and poll status_url; do not resubmit
Message keeps failingCap 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

All Developers posts

Written by Sume