An operation you can safely apply more than once and get the same result: the foundation of every retryable system.
Submit a payment, then hit retry (like a flaky network would).
Networks retry. Without an idempotency key, a retried "charge card" runs twice. With one, the server remembers the key, so the duplicate returns the original result instead of doing the work again. Essential for anything that moves money or sends messages.
Plain English: 'set my balance to $100' is idempotent, so running it twice doesn't double-set anything. 'Add $10 to my balance' is NOT, so running it twice charges me extra. Networks lose responses constantly, so any operation that matters has to be designed so a retry doesn't break things.
A property of an operation: F(x) == F(F(x)) == F(F(F(x))). 'Set balance to $100' is idempotent. 'Add $10 to balance' is not: retry it and the user is overcharged. Idempotency is what makes networks tolerable. Networks lose responses, timeouts lie, retries happen, and without idempotency, every retry is a potential bug.
Every distributed system has at-least-once delivery somewhere. A request times out, the client retries, the server processes both, and now what? Without idempotency, you get duplicate charges, doubled inventory adjustments, duplicate emails. With idempotency, the second request is a no-op or returns the cached result.
Three common patterns: (1) Idempotency keys, where the client sends a unique key with each request; the server records it and returns the cached response on retry (Stripe's model). (2) Natural idempotence, where you design the operation so it's inherently safe to repeat (PUT, upserts, 'set' instead of 'add'). (3) Versioned writes, where you include an expected version; the second write fails the optimistic-lock check and is a no-op.
Idempotency keys on every charge request, Stripe-style. Duplicate POSTs return the original response, no double-charge
At-least-once delivery is the default. Consumers must be idempotent, processing the same message twice without effect
Send-notification accepts an idempotency key so a flaky publisher's retries don't spam the user
A race condition in charge creation caused duplicate charges when clients retried on a slow response.
Stripe's charge API occasionally returned a timeout to clients. The HTTP connection dropped before the response arrived, even though the charge had already been created on Stripe's side. Well-behaved clients, following Stripe's own retry guidance, retried the request. Without idempotency keys, Stripe's backend treated the retry as a new charge and created a second one. Thousands of customers were double-billed before the incident was caught. Stripe rolled out idempotency key enforcement as a first-class API primitive: clients send a unique key per intended charge, and the backend deduplicates on that key no matter how many times the request arrives. The lesson: any operation that charges money, sends a message, or has real-world side effects must be idempotent end-to-end. Timeouts aren't errors; they're ambiguous. Design your API for that ambiguity.
Idempotency comes up in any payment or critical-write scenario. The interviewer wants you to say 'at-least-once delivery is fine as long as the consumer is idempotent' rather than trying to build exactly-once delivery (which is extremely expensive). Name the pattern: idempotency key sent by the client, stored by the server, with the result cached for the retry window. Candidates lose points by treating retries as a network problem to solve rather than a data design problem to absorb.