Idempotency Keys
You'll learn to
- -Implement idempotency keys so a retried POST request never double-processes (e.g. double-charges) an operation
- -Explain why POST needs an explicit idempotency mechanism when PUT and DELETE are already naturally idempotent
GET, PUT, and DELETE are naturally idempotent by the HTTP spec's own definition - but POST, used for creating resources and triggering actions, is explicitly not, which becomes a real production problem the moment a network timeout happens: the client never received a response, but the request may well have already succeeded on the server. Does the client retry, and risk creating the resource (or charging the payment) twice?
The Idempotency-Key Header
POST /payments
Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7
{"amount": 4999, "currency": "usd", "customer_id": 42}
HTTP/1.1 201 Created
{"id": "pay_501", "status": "succeeded"}
# The exact same request, retried after a timeout - same key, same body:
POST /payments
Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7
{"amount": 4999, "currency": "usd", "customer_id": 42}
# Server recognizes the key was already processed - returns the ORIGINAL
# result again, without charging a second time:
HTTP/1.1 201 Created
{"id": "pay_501", "status": "succeeded"}The client generates a unique key (typically a UUID) once per logical operation, before the first attempt, and sends the same key on every retry of that same operation. The server stores a mapping from idempotency key to the result it already produced - a retried request with a seen key returns the stored result directly, without re-executing the underlying action.
What Happens on a Body Mismatch
POST /payments
Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7
{"amount": 9999, "currency": "usd", "customer_id": 42}
HTTP/1.1 409 Conflict
{"error": "Idempotency-Key already used with a different request body"}If the same key shows up with a genuinely different body, that is not a legitimate retry - it is either a client bug (accidentally reusing a key) or an attempt to piggyback a different operation on an already-consumed key. Returning 409 rather than silently processing the new body (or silently returning the old result) surfaces the mismatch instead of hiding a real bug.
A Reasonable Retention Window, Not Forever
Idempotency keys don't need to be stored indefinitely - a retry that matters happens within seconds to minutes of the original attempt, not months later. A bounded retention window (commonly 24 hours) is enough to cover realistic retry scenarios without the storage cost of an ever-growing key table.
This is the exact same idempotency-key pattern covered for financial ledgers in LLD Fundamentals' money-modeling chapter - here it's the API-facing half of the same underlying problem: preventing a network-level retry from becoming a duplicate business operation.
Interview Signal is part of Pro
See a real weak answer next to a real strong one for this exact topic.
Quiz is part of Pro
Test what you just read with a short quiz, and bank the XP.
Design Idempotency Shield in the API Design Lab's Production Patterns act.