SQS FIFO 5-minute dedup vs a Sume Idempotency-Key: which wins?
SQS FIFO dedupes for only 5 minutes. A Sume Idempotency-Key covers the create call itself, so use both when a worker can retry after the window.

They protect different hops, so use both. SQS FIFO deduplicates messages sent within a 5 minute interval, using either a MessageDeduplicationId or, with content-based deduplication, a SHA-256 of the body. That stops duplicate enqueues. It does not stop a worker that crashes after calling Sume and gets the message again, and it does not help after the window. A Sume Idempotency-Key does that job at the API.
What each layer covers
| Layer | What it dedupes | Limit |
|---|---|---|
| SQS FIFO deduplication | Duplicate sends to the queue | 5 minute interval |
| Consumer retry after crash | Not covered by SQS dedup | Visibility timeout redelivery |
| Sume Idempotency-Key | Duplicate create calls | Same key and body returns the original |
Where duplicates still appear
Suppose a Lambda or container reads a message, calls Sume, and times out before deleting the message. The message becomes visible again and a second worker repeats the call. SQS dedup is irrelevant here, because the message was sent once. With a fixed Idempotency-Key built from the message's business id, the second call returns the original job instead of creating another paid one.
Conversely, if a producer re-sends the same business event ten minutes later, SQS will accept it as new. The Sume key still matches, provided the body is the same.
Pick the key carefully
Use the same value for the SQS dedup id and the Sume key if you can: one identity per business event. Do not use a random UUID created in the consumer, since each retry would invent a new one.
- Same key plus a different body returns 409
idempotency_conflict; treat it as a bug and alert. - On 429
rate_limitedhonour retry-after; on 402insufficient_creditsdo not retry. - For Format runs the replay returns 200 with
idempotency_hit: true, so check for it instead of assuming a 202.
Finish the loop with a webhook
After a 202 the consumer should delete the message and store the job id. Completion comes back through job.completed, job.failed or job.canceled, deduped on job_id. Do not keep the SQS message invisible while a video renders; the generation is not tied to your queue's timeout, and a client timeout does not cancel a running job.
Sources
Related posts
More in Developers
- StepAudio 3 Music preview is free, then retired: keep your API stable
stepaudio-3-music-preview is free for a limited time, then retired for a paid version. How to keep a music integration stable, and which Sume ids stay put.
- Stripe wants enabled_events trimmed; Sume sends only terminal events
Stripe advises subscribing only to needed event types. Sume sends only terminal job and run events, with the URL set on each request. Here is the mapping.
- Stripe resend keeps auto-retries; Sume redeliver uses no attempt
Stripe's manual resend does not cancel automatic retries and works 15 to 30 days. Sume redeliver sends a fresh signature after ten attempts and keeps the URL.
- Stripe says one restricted key per service: Sume scopes per job
Stripe recommends restricted keys, one per service. Sume keys have fixed scopes. Map each webhook operation to its scope and give the handler no more.
Written by Sume