Idempotency Keys, Practically
A working note on making write endpoints safe to retry without bolting on a distributed transaction.
Last tended
Retries are not an edge case — they are the default behavior of every network. The question is never if a request arrives twice, only when.
The minimum viable contract
The client generates a key (a UUID is fine) and sends it with the write:
POST /payments
Idempotency-Key: 5f9c...e21
The server stores the key before doing the work, scoped to the endpoint and the caller. Three outcomes:
- New key → process, persist the response against the key, return it.
- Key in flight → return
409and let the client back off. - Key complete → replay the stored response verbatim. No re-execution.
What people get wrong
- Hashing the request body instead of a client key — now a legitimate “same request, new intent” is silently swallowed.
- Storing the key after the side effect, leaving a crash window.
- Forgetting a TTL, so the key table grows forever.
Idempotency is a property you design into the write, not a middleware you add later.