What Is Idempotency? β Definition and How It Works
Learn what idempotency means, why it is the property that makes retries safe, and how to design operations that have it.
An operation is idempotent when performing it more than once has the same effect as performing it once. It is the property that makes retries, replays, and at-least-once delivery tolerable.
1. Why Distributed Systems Need It
The fundamental problem is that a failed response does not tell you whether the operation happened.
You send a request. The connection drops before a response arrives. Three possibilities are indistinguishable from your side: the request never arrived, it arrived and succeeded but the response was lost, or it arrived and failed.
If the operation is idempotent, you do not need to know β retry, and the result is correct either way. If it is not, you must either risk duplication or risk loss.
That is the whole reason the property matters, and it explains why "exactly once" is generally achieved as "at least once delivery plus idempotent handling" rather than as a delivery guarantee.
2. Idempotent, Not Just Read-Only
A common confusion: idempotent does not mean "does not change anything".
| Operation | Idempotent | Why |
|---|---|---|
| Read a value | Yes | No change at all |
| Set a value to 5 | Yes | Repeating leaves it at 5 |
| Add 5 to a value | No | Repeating adds again |
| Delete a record | Yes | Already gone |
| Append to a list | No | Grows each time |
| Mark a flag true | Yes | Already true |
The pattern: assignment is idempotent, accumulation is not. Redesigning an accumulation as an assignment is the most common way to gain the property.
3. Techniques for Making Operations Idempotent
Assign instead of increment. Store the computed total rather than adding a delta.
Deduplicate on a natural key. An operation keyed on something derived from the data can detect a repeat.
Use a client-generated request key. The caller sends a unique identifier; the server records it with the result and returns the stored result on a repeat.
Make the effect conditional. "Set state to X if it is currently Y" is safe to repeat, because the second attempt finds the condition false.
Include a version or timestamp guard. "Update only if newer" prevents a replayed old message overwriting newer state.
4. Idempotency Keys in Practice
key = str(uuid4()) # generated ONCE, before the first attempt
for attempt in range(3):
try:
return post("/payments", json=body, headers={"Idempotency-Key": key})
except Timeout:
continue # same key, so a duplicate is impossible
The critical detail is that the key is generated before the loop. Generating it inside means each retry is a new operation, which defeats the mechanism entirely β and this is the most common implementation error.
5. Idempotency Has a Scope
A key cannot be remembered forever. Servers retain them for a window β hours or days β after which a repeat is treated as new.
That is fine for retries, which happen in seconds, and a trap for replaying an old queue backlog days later. Any replay strategy needs to know the retention window it is operating inside.
6. Where It Appears
- HTTP methods β GET, PUT, and DELETE are idempotent; POST and PATCH are not.
- Message consumers β at-least-once delivery means every handler must tolerate a duplicate.
- Data pipelines β a re-run must not duplicate rows.
- Infrastructure as code β declaring desired state is idempotent by design.
- Migrations β a guard makes a re-applied migration harmless.
7. Summary
Idempotency means repeating an operation has no additional effect, which is what allows a retry after an ambiguous failure β the case where you cannot tell whether the first attempt succeeded.
Gain it by assigning rather than accumulating, deduplicating on a natural key, adding a client-generated request key created once before the first attempt, or guarding the effect with a condition or version β and remember that key retention has a window, so old replays are not covered by it.