पाठ 15 / 25
Idempotency
Retries without double charges.
Idempotency keys
Networks time out after the server has done the work, so clients retry, and queues redeliver. An operation is idempotent if repeating it has the same effect as doing it once. For non-idempotent actions such as payments, the client sends an idempotency key; the server stores the result per key and returns the stored result on repeats instead of acting again. Store keys with the result atomically and expire them after a sensible window.
A retried payment charged only once, run
I ran this with Python 3.12.3 using only the standard library; inputs are fixed or seeded, so the output is reproducible. The retry with the same key returns the stored result marked as replayed, and only two real charges happen for three calls.
# Idempotency keys make retried payment requests safe
import uuid
class PaymentAPI:
def __init__(self):
self.results, self.charged = {}, []
def charge(self, key, amount):
if key in self.results: # replay: return the stored result
return self.results[key] | {"replayed": True}
self.charged.append(amount) # the real side effect happens once
result = {"status": "succeeded", "amount": amount, "replayed": False}
self.results[key] = result
return result
api = PaymentAPI()
key = str(uuid.UUID(int=42)) # fixed key for a reproducible demo
print(api.charge(key, 499))
print(api.charge(key, 499)) # client timed out and retried
print(api.charge(str(uuid.UUID(int=43)), 499)) # a genuinely new payment
print("total charged:", sum(api.charged))
Output:
{'status': 'succeeded', 'amount': 499, 'replayed': False}
{'status': 'succeeded', 'amount': 499, 'replayed': True}
{'status': 'succeeded', 'amount': 499, 'replayed': False}
total charged: 998Design consumers to be idempotent
Upserts, deduplication tables and conditional updates make at-least-once delivery safe.
त्वरित जाँच: What should a server do when it receives a repeated idempotency key?
- Return the stored result without repeating the side effect
- Charge again
- Return an error and lose the result
- Ignore the key and process normally
Answer
Return the stored result without repeating the side effect — Same effect as once.