I recommend idempotency for every path where retries can create real damage. Payments, orders, emails, and inventory reservations should survive duplicate requests without duplicate business effects.
The key is part of the contract
I need to know what the system does when messages arrive late, arrive twice, or never arrive.
An idempotency key lets the server recognize that a retry is the same business attempt. The server stores the first result and returns it again instead of performing the action twice.
Payment request example
I use the real workflow as the test. If it falls apart there, the pattern is still theory.
A mobile app sends a payment request and loses the response. It retries with the same idempotency key. The payment service finds the original result and returns the receipt.
Idempotent write code
I want the snippet to expose the guardrail, not hide it behind framework noise.
Store the first result and return it for the same business attempt:
Receipt charge(String idempotencyKey, ChargeRequest request) {
return receipts.computeIfAbsent(
idempotencyKey,
key -> paymentGateway.charge(request));
}
The idempotency key makes retries safe: the first request creates the charge, and later requests with the same key return the saved receipt instead of charging again.
Sequence diagram: retry without double charging
The retry is safe because the server recognizes the business attempt, not just the network request.
The duplicate policy
- Choose keys from the client workflow, not random server calls.
- Store enough response data to answer retries consistently.
- Expire keys only after the business risk window is closed.