All concepts
Reliability

Idempotency

Processing the same message twice must yield the same result.

Why it matters

Because standard queues deliver at-least-once, and even FIFO can re-deliver after a visibility timeout, every consumer must be idempotent.

Why it's required

Amazon SQS may deliver the same message more than once. Standard queues do so by design (at-least-once). FIFO queues can re-deliver if a consumer doesn't delete before visibility timeout expires. Applications must not be adversely affected when processing duplicates.

Pattern: idempotency key + dedup store

Use a business-level idempotency key (order ID, event ID). Before doing work, attempt to insert the key into a deduplication table with a uniqueness constraint. If insert fails, skip work and delete the SQS message.

INSERT INTO processed_events (idempotency_key)
VALUES ($1)
ON CONFLICT DO NOTHING
RETURNING idempotency_key;

Pattern: conditional writes

When the side effect is a single database operation, use conditional INSERT or UPDATE keyed by message ID or business key so a duplicate delivery is a no-op.

External API calls

When calling payment processors, email providers, or other external APIs, pass your idempotency key as the provider's idempotency header (e.g. Stripe Idempotency-Key). Without this, duplicate SQS deliveries can cause duplicate charges or notifications.

What NOT to use as a key

SQS MessageId can differ between deliveries of logically the same message in some scenarios. Prefer producer-assigned business identifiers that are stable across retries.

  • Good: orderId, paymentIntentId, eventUuid from upstream.
  • Risky: SQS MessageId alone, timestamps added at consume time.
Gotchas
  • !MessageId may not be stable across all redelivery scenarios — use a producer-side business key.
  • !Calling external APIs without idempotency keys can result in duplicate charges or sends.
  • !Idempotency at the consumer does not replace FIFO deduplication at the producer — use both where needed.
Try the Duplicate orders lab
Apply this concept to a broken system.
open →