Idempotent Receiver
Definition
An idempotent receiver is a server or message consumer that can process the same request many times while changing the system only once. The client tags each request with a stable id and a request number, and the server stores the result of every request it handles. When a retry arrives with a number it has already seen, the server replays the saved response instead of redoing the work. This makes retries safe under at-least-once delivery, where duplicates are guaranteed rather than rare.
Key Takeaways
- Duplicates are not a bug, they are a guarantee. The moment a client retries on timeout, the server will eventually see the same request twice.
- The pattern has three parts: a stable client id, a per client request number, and a saved response that gets replayed on a duplicate.
- Idempotency is about the effect, not the message. Receiving a message twice is fine as long as the charge, insert, or send happens once.
- The side effect and the dedup record must commit together, in one transaction or via a transactional outbox, or a crash in between will charge twice.
- An at-least-once channel plus an idempotent receiver gives you effectively once processing, which is the practical answer to exactly once delivery.
How It Works
- Each client registers and gets a stable id, and every request it sends carries a monotonically increasing request number.
- The server keeps a small record per client: the highest request number it has processed and the response it produced.
- On a new request, the server does the work and records the id plus response as one atomic step, often using a unique constraint on the key.
- On a duplicate, the server finds the saved response and returns it without running the logic again.
- Old records are dropped using a client acknowledged low water mark, a session lease, or a TTL so the dedup store stays bounded.
Where It Is Used
- Stripe idempotency keys: send an Idempotency-Key header and a retry with the same key returns the first result instead of charging the card twice.
- Kafka idempotent producers assign a producer id and a per partition sequence number so the broker drops a retried record it has already written.
- Raft and other consensus systems use client sessions with serial numbers so a command retried during a leader change is not applied twice.