This question tests whether you understand idempotency as a mechanism rather than a marketing term. The interviewer wants the concrete machinery: where the key lives, where it's checked, and what happens on a duplicate.
The mental model: make the side effect a function of the key, not of the request.
The client generates a key — a UUID, Stripe-style — and sends it in an Idempotency-Key header. The server's contract: two requests carrying the same key run the side effect at most once, and the duplicate gets the original response.
The check happens before the side effect, against a store that can enforce uniqueness — typically a database table with a unique constraint on the key column. The lookup path: if the key exists, return the stored response and do no work. If it misses, insert the key with status in-progress, run the handler, and on completion update the row atomically with the response body and status done. The unique constraint is what makes the race safe: two concurrent duplicates both miss, both try to insert, one wins, and the loser hits a constraint violation and waits for the winner to finish before returning the stored result.
Two design details matter. First, the retention window: keys must outlive the client's retry horizon — Stripe keeps them for 24 hours. Second, the boundary of protection: idempotency guards the write path. Reads are naturally idempotent, and a non-idempotent effect like an increment must be expressed as an absolute operation ("set balance to X") rather than a relative one ("add 5") — or it must be rewritten so the key lookup short-circuits it entirely.
Tradeoffs and edge cases: the key store is now on the critical path of every write, so it must be fast and highly available — in effect it's a lock. Expired keys mean an old retry can double-execute, so clients must not retry outside the window. And a request that crashes mid-handler leaves a stale in-progress row; the server needs a timeout after which a stuck key is treated as expired and re-executed, rather than returning a half-finished result forever.