Jul 25, 2026 · 5 min read
Idempotency keys: making retries safe
Any system that talks over a network eventually hits the same awkward moment: a request goes out, the connection drops before the response comes back, and the caller has no idea whether the work actually happened. The safe-looking move — retry — is exactly what turns one payment into two.
The fix is an old one, and I reach for it constantly: idempotency keys. The client generates a unique key per logical operation and sends it with every attempt. The server records that key alongside the result of the first successful run; any later request carrying the same key returns the stored result instead of doing the work again.
What makes it work
- The key is per-intent, not per-request. Every retry of "charge this cart" shares one key; a genuinely new charge gets a new one.
- Store the outcome, not just the key. On a repeat you return the original response — same status, same body — so the caller can't tell a retry from the first call.
- Make the write and the key-record atomic. If they can diverge, you reintroduce the double-execution you were trying to prevent.
The subtle case is concurrency: two attempts arrive almost at once. I handle it by making the key a uniqueness constraint — the first writer wins, and the second either waits for the result or is told the operation is already in progress.
It costs a table and a little discipline at the boundary. In return, "just retry it" stops being dangerous — which, for anything touching money or state, is the difference between a resilient system and a 2 a.m. page.