EssaySystemsOct 2026 · 7 min

Idempotency keys are a promise about time

A key says "if you send this again, nothing new happens". The part people forget is the "for how long".

Scroll to advance. The figure keeps running while you read.

{{ t.k }}
Fig. 3.6
{{ statLabel }} {{ stat }}
01 · The lost response

A client sends a charge and the connection drops. It can't tell whether the charge happened. The only safe thing it can do is send it again.

02 · The key

The client creates one key per intent and sends it with every attempt. The server stores the key with the result. A repeat gets the stored result back.

03 · Two at once

Two attempts can arrive together. The first INSERT of the key wins. The other is told the request is in progress and to ask again shortly.

04 · Same key, new body

If the payload changed, it isn't the same request. Store a hash of the body with the key and reject a mismatch instead of replaying the wrong answer.

05 · The window

Keys are not kept forever. A common choice is 24 hours. After that, the same request is a new charge. The key was always a promise with an expiry date.

06 · Choosing it

The window must be longer than the longest retry anyone will make: queues that redeliver, phones that were offline, batch jobs that replay a day. Retries arrive later than you expect.

07 · The promise

Write three things in the API docs: how long a key lives, what it is scoped to, and what is stored: the full response, not just "seen".

Three things to keep
1 keyper intent, reused on every attempt.
24 hor whatever you choose, as long as it is written down.
> maxretry delay, or the promise breaks quietly.

Related machine: An idempotent ledger →

← Where old rows go Found a mistake? Tell me and I'll fix it. All notes →