What is idempotency?
Simply put: the first call does the work, all subsequent calls — nothing new happens.
Junior Level
Idempotency is a property of an operation where repeated calls with the same parameters do not change the result after the first execution.
Simply put: the first call does the work, all subsequent calls — nothing new happens.
In simple terms: no matter how many times you execute the operation, the result is the same as after the first time.
Real-life examples:
- Idempotent: Turn off the light. No matter how many times you press “off” — the light stays off.
- Not idempotent: Buy a ticket. Each purchase is a new ticket and a new charge.
In HTTP context:
- GET /users/1 — idempotent. No matter how many times you request it — data doesn’t change.
- DELETE /users/1 — idempotent. First call deletes, subsequent calls confirm the resource is gone.
- POST /users — not idempotent. Each call creates a new user.
Why is this needed?
Idempotency allows safely retrying requests on network errors without fear of creating duplicates.
Middle Level
Mathematical Definition
f(x) = f(f(x)) — the result of applying a function multiple times equals the result of applying it once.
// In HTTP, idempotency concerns server state, not the response code. // The mathematical formula here is an analogy, not a strict definition.
Idempotent HTTP methods:
- GET, HEAD, OPTIONS — safe and idempotent (don’t change state)
- PUT — idempotent (full replacement:
status = 'ACTIVE'ten times ='ACTIVE') - DELETE — idempotent (first call deletes, rest confirm absence)
Non-idempotent methods:
- POST — usually creates new resources. 5 requests
POST /orders= 5 orders - PATCH — depends on implementation.
{"age": 30}— idempotent,{"op": "add", "path": "/tags"}— not
Idempotency vs Response Code
DELETE returned 200, second call — 404. It’s still idempotent! Idempotency guarantees identical system state, not the response code.
Safe vs Idempotent
A safe method (GET) doesn’t change state. An idempotent method (PUT, DELETE) can change state, but only once. All safe methods are idempotent, but not vice versa.
PRG Pattern (Post/Redirect/Get)
Solution to POST non-idempotency in web interfaces:
- User clicks “Pay” (POST)
- Server processes and sends 303 See Other
- Browser makes a GET to the success page
- On F5, a safe GET is repeated, not a dangerous POST
When non-idempotency is desirable
Audit logs, event sourcing, financial transactions — each attempt must be recorded, even if the result is the same.
Senior Level
Idempotency Key Implementation for POST
In high-load systems (payments, orders), the Idempotency Key pattern is used:
Server algorithm:
- Accept: Receive header
Idempotency-Key: <UUID> - Check: Look up the key in Redis with TTL (e.g., 24 hours)
- States:
- Key doesn’t exist: Create record with status
PROCESSING. Execute logic. Update toCOMPLETED, save the response. - Status
PROCESSING: Return409 Conflict(prevents Race Condition) - Status
COMPLETED: Return the saved response from Redis. Business logic is not re-executed.
- Key doesn’t exist: Create record with status
Distributed Computing
Networks are unreliable (Fallacies of Distributed Computing). A request may:
- Never reach the server
- Be processed, but the response is lost
- Hang (Timeout)
Idempotency allows the client to safely retry the request.
Performance and Highload
- Distributed Locks: Redlock adds latency
- Storage Cleanup: Storing responses for 24 hours can take significant space in Redis
- DB Level:
INSERT ... ON CONFLICT DO NOTHING(PostgreSQL) — a reliable “last line of defense”
Edge Cases
- If
Idempotency-Keyis the same but the body differs — return400 Bad Request - Idempotency concerns the primary resource. Side effects (logging, analytics) are acceptable
- When testing an API, always make two identical calls in a row to verify
Interview Cheat Sheet
Must know:
- Idempotency: repeated call with the same parameters doesn’t change the result after the first execution
- Formula: f(x) = f(f(x)) — the result of multiple applications equals a single application
- Idempotent methods: GET, HEAD, OPTIONS, PUT, DELETE
- Non-idempotent: POST (usually), PATCH (depends on implementation)
- Idempotency concerns server state, not the response code (DELETE 200 -> 404 — still idempotent)
- Safe methods (GET, HEAD) don’t change state; all Safe methods are idempotent, but not vice versa
- PRG pattern (Post/Redirect/Get) solves the POST form resubmission problem
- Idempotency Key: UUID in header + Redis lock for safe POST retries
Frequent follow-up questions:
- Why is DELETE idempotent if the second time it returns 404? — Idempotency = same server state, not same response code
- How to make POST idempotent? — Idempotency-Key in header + storing the result in Redis
- What is a Retry Storm? — When thousands of clients simultaneously retry idempotent requests
- Why is a Distributed Lock needed with Idempotency Key? — To prevent Race Conditions on concurrent requests
Red flags (DO NOT say):
- “Idempotency means the same response code” — it means the same server state
- “POST can’t be made idempotent” — it can via Idempotency Key + distributed lock
- “PATCH is always non-idempotent” — depends on the operation (replace — idempotent, add — not)
- “Idempotency and Safe are the same” — Safe doesn’t change state, idempotent can change but only once
Related topics:
- [[Which HTTP methods are idempotent]]
- [[Why GET and DELETE are idempotent]]
- [[Is POST idempotent]]
- [[What are the main HTTP methods used in REST]]
- [[What is the difference between PUT and PATCH]]