Idempotency
An operation that produces the same result whether you run it once or multiple times. Critical for safe retries in distributed systems.
What is Idempotency?
In short
Idempotency is the property of an operation that produces the same end result no matter how many times you run it with the same input. Sending a request once or five times leaves the system in the identical state, which is what makes it safe to retry a failed network call without creating duplicate charges, duplicate orders, or corrupted data.
What idempotency actually means
An operation is idempotent if running it twice has the same effect as running it once. Setting a value to 5 is idempotent: assign x = 5 a hundred times and x is still 5. Incrementing a counter is not idempotent: x = x + 1 run three times gives a different result than running it once.
In HTTP this is built into the method semantics. GET, PUT, and DELETE are defined as idempotent. GET reads and changes nothing. PUT replaces a resource with a full representation, so repeating it overwrites with the same data. DELETE removes a resource, and deleting an already-deleted resource leaves the same end state (gone). POST is the odd one out: it is not idempotent, because each POST is meant to create a new resource, so two POSTs create two records.
The word matters because networks are unreliable. A client sends a request, the server processes it, and the response gets lost on the way back. The client cannot tell whether the operation succeeded or failed, so it retries. If the operation is idempotent, the retry is harmless. If it is not, the retry can double-charge a card or place a second order.
How idempotency keys work under the hood
Most real systems need to make a non-idempotent operation like a payment safe to retry. The standard technique is an idempotency key: a unique token the client generates (usually a UUID) and sends with the request, often in an HTTP header like Idempotency-Key.
On the first request, the server records the key together with the result of the operation in a store such as Redis or a Postgres table, then returns the response. If the same key arrives again, the server sees it has already processed that key and returns the saved response instead of executing the operation a second time. The charge happens exactly once even if the client retries ten times.
Two details make or break this. First, the lookup and the write must be atomic, usually a database row with a unique constraint on the key, so two concurrent retries cannot both slip through. Second, keys need a time-to-live. Stripe keeps idempotency keys for 24 hours, after which the same key can be reused. The client must generate a fresh key per logical operation, not per retry, so all retries of the same intent share one key.
When to use it and the trade-offs
Use idempotency wherever a retry could cause damage: payment APIs, order placement, sending email or SMS, message consumers reading from a queue, and any write endpoint behind a load balancer or proxy that might re-send on timeout. Message systems like Kafka and SQS deliver at least once, meaning duplicates are expected, so consumers must be idempotent to be correct.
The cost is real but small. You need somewhere to store keys and their results, you pay an extra lookup on every write, and you have to decide on a TTL and a key-generation scheme. Storing the full response so retries get an identical answer adds more storage than just storing a boolean.
The common mistake is assuming a database unique constraint alone gives you idempotency. It prevents duplicate rows, but the client still gets an error on the retry instead of the original success response, which often triggers more retries. True idempotency returns the same successful answer to the duplicate request, not an error.
A concrete example: Stripe payments
Stripe is the textbook case. When you create a charge, you pass an Idempotency-Key header with a UUID you generate. If your server times out waiting for Stripe and you retry with the same key, Stripe recognizes it and returns the original charge object rather than charging the customer twice.
Picture an e-commerce checkout. The shopper clicks Pay, the browser sends the request, but the mobile connection drops before the confirmation arrives. The app retries automatically. Without an idempotency key, the customer is charged twice and you get a chargeback and a support ticket. With the key generated once at checkout and reused across retries, the second request is a no-op that returns the same success.
The same pattern shows up everywhere money or side effects are involved. PayPal, Adyen, and most modern payment processors expose idempotency keys, and internal microservices copy the design for their own write endpoints.
Where it is used in production
Stripe
Accepts an Idempotency-Key header on write requests and stores the result for 24 hours so retried charges return the original response instead of double-charging.
Apache Kafka
Offers an idempotent producer (enable.idempotence=true) that deduplicates retried sends so a record is written exactly once per partition despite retries.
Amazon SQS
Standard queues deliver at least once, so consumers must process messages idempotently; FIFO queues add deduplication IDs within a five-minute window.
PayPal
Its REST APIs support a PayPal-Request-Id header that acts as an idempotency key so retried order and capture calls do not create duplicate transactions.
Frequently asked questions
- Is POST idempotent?
- No. By definition each POST creates a new resource, so sending it twice creates two records. You make POST safe to retry by adding an idempotency key the server uses to detect and ignore duplicates.
- What is the difference between idempotency and safety in HTTP?
- A safe method (GET, HEAD) does not modify state at all. An idempotent method may modify state but produces the same end result on repeats. All safe methods are idempotent, but PUT and DELETE are idempotent without being safe because they change data.
- How long should an idempotency key be stored?
- Long enough to cover realistic retry windows but not forever. Stripe keeps keys for 24 hours. The store usually has a TTL so old keys expire and the same value can be reused for a new operation later.
- Does a database unique constraint give me idempotency?
- Partially. It blocks duplicate rows, but the retry receives a constraint-violation error instead of the original success, which can trigger more retries. Full idempotency means returning the same successful response to the duplicate request, so you usually store and replay the original result.
- Why do message queue consumers need to be idempotent?
- Systems like Kafka and SQS guarantee at-least-once delivery, meaning the same message can be delivered more than once after a failure or rebalance. If processing the same message twice would double-count or double-send, the consumer must dedupe, typically by tracking a message ID or using an idempotency key.
Learn Idempotency hands-on
This page explains the idea. The full lesson lets you step through the ring as servers join and leave, read the implementation, and check yourself with a quiz. It is one of 760+ lessons in the System Design Masterclass, from your first API call to distributed consensus. Eleven Foundation lessons are free, no signup. Lifetime access is ₹499 in India or $7.99 worldwide, one payment, no subscription.
Related lessons
Lessons that touch on Idempotency as part of a larger topic.
Idempotency Keys
Safely retry failed API requests without causing duplicate side effects
intermediate · api design protocols
Design a Payment System
Design a payment processing system - ACID transactions, idempotency, reconciliation, retry strategies, and the saga pattern for distributed payments
capstone · capstone
Message Deduplication
Detect and discard duplicate messages before they cause double-processing
intermediate · messaging event systems
Idempotent Consumer
Design consumers that produce the same result whether a message is processed once or ten times
intermediate · messaging event systems
Exactly-Once Delivery
The holy grail of messaging, process every message once and only once. Here's why it's nearly impossible and how to fake it.
intermediate · messaging event systems
See also
Related glossary terms you might want to look up next.
REST API
An architectural style for building APIs using standard HTTP methods (GET, POST, PUT, DELETE). Resources are identified by URLs.
Retry
Automatically re-attempting a failed operation, usually with exponential backoff. Essential for handling transient failures in distributed systems.
HTTP
The protocol powering the web. A request-response model where clients ask for resources and servers respond. Stateless by design.
Latency
The time delay between sending a request and getting a response. Amazon found every 100ms of extra latency costs 1% in sales.
Throughput
The number of operations a system can handle per unit of time. Think of it as how many cars a highway can move per hour.
Bandwidth
The maximum amount of data that can be transferred over a network in a given time. It's the width of the pipe, not how fast the water flows.