Idempotency
Network failures are inevitable. Clients will retry requests. Without idempotency, retries can cause catastrophic bugs — a payment system that charges.
Quick answer: Idempotency
Idempotency is covered here as a practical system design concept. Network failures are inevitable. Clients will retry requests. Without idempotency, retries can cause catastrophic bugs — a payment system that charges. Use it to understand the APIs idea, where it appears in production systems, and how to discuss it clearly in interviews.
Focus on the problem being solved, the main design choice, the failure mode, and the tradeoff you would defend in front of a senior engineer. This page is part of the DosiBridge system design knowledge graph, so it links related concepts, interview problems, tradeoffs, and references instead of leaving the topic isolated.
An operation is idempotent if performing it multiple times produces the same result as performing it once. In APIs, idempotency ensures that retrying a request (due to network timeouts, client errors, or duplicate submissions) does not cause unintended side effects like double charges, duplicate orders, or redundant emails.
Why This Matters
Network failures are inevitable. Clients will retry requests. Without idempotency, retries can cause catastrophic bugs — a payment system that charges twice, an order system that ships duplicate items. Idempotency is essential for reliable distributed systems.
The Building Blocks
- Naturally idempotent: GET, PUT, DELETE are idempotent by design. Getting the same resource twice returns the same result. Deleting a resource that is already deleted is a no-op.
- Not naturally idempotent: POST is not idempotent — posting an order twice creates two orders. You must add idempotency explicitly.
- Idempotency keys: The client sends a unique key (UUID) with each request. The server stores the key and result. If the same key arrives again, the server returns the cached result without re-executing.
- Database-level idempotency: Use unique constraints (ON CONFLICT DO NOTHING) or conditional writes (IF NOT EXISTS) to prevent duplicates.
- At-least-once delivery: Many message queues deliver messages at least once. Your consumer must be idempotent.
Under the Hood
For payment APIs: The client generates an idempotency key (UUID) and sends it with the payment request header. The server checks if this key exists in a store (Redis). If yes, return the stored result. If no, process the payment, store the result keyed by the idempotency key, and return the result.
This ensures that even if the client retries 10 times, the payment is only charged once.
How Companies Actually Do This
Stripe requires an Idempotency-Key header on all POST requests. Retrying with the same key returns the original response.
Amazon SQS provides at-least-once delivery. Consumers must be idempotent to handle duplicate messages.
Airbnb uses idempotency keys in their payments system to prevent double-charging guests.
Common Pitfalls
- Not implementing idempotency for payment or order APIs — guaranteed double-charge bugs
- Setting idempotency key TTL too short — client may retry after the key expires
- Using non-unique idempotency keys — defeats the entire purpose
Interview Questions Worth Practicing
- What is idempotency and why is it important?
- Which HTTP methods are naturally idempotent?
- How do you implement idempotency in a payment system?
- What is at-least-once vs exactly-once delivery?
The Tradeoffs
- Storage overhead: Storing idempotency keys and results requires extra storage and TTL management.
- Complexity: Adding idempotency logic to every endpoint adds development time.
- Concurrency: Two identical requests arriving simultaneously may both miss the key check — use database locks or compare-and-swap.
Related Topics
Original DosiBridge notes for Idempotency
This section is written specifically for this page, not copied from a general system-design checklist. The useful way to study Idempotency is to connect the concept to a production service where growth exposes the first weak assumption in the original design. That framing changes the design discussion from definitions to operating choices.
What makes this topic distinct
- Contract Evolution: For Idempotency, decide the contract evolution before choosing tools; otherwise the design looks clean but fails when idempotency changes.
- Idempotency: For Idempotency, decide the idempotency before choosing tools; otherwise the design looks clean but fails when idempotency changes.
- Pagination: For Idempotency, decide the pagination before choosing tools; otherwise the design looks clean but fails when idempotency changes.
- Error Shape: For Idempotency, decide the error shape before choosing tools; otherwise the design looks clean but fails when idempotency changes.
- Consumer Compatibility: For Idempotency, decide the consumer compatibility before choosing tools; otherwise the design looks clean but fails when idempotency changes.
Production review question
If a team adopts Idempotency, what observable signal proves it helped instead of only making the architecture diagram more fashionable?
Practical metric to track
Track idempotency health as a named dashboard or review item: combine one user-facing metric, one saturation metric, and one correctness metric. For Idempotency, this keeps the discussion grounded in behavior that can be measured after deployment instead of generic advice that sounds good in an interview but never gets verified.