Microservices Idempotency
Networks fail in sneaky ways. A client sends a payment request, the server completes it, and the reply gets lost. The client tries again and risks a second charge. Idempotency solves this problem: repeating the same request produces the same result as running it once.
Layman Explanation
Pressing the elevator call button five times still brings one elevator. The extra presses change nothing. A well-built service treats duplicate requests the same way and ignores the extra presses.
Naturally Idempotent Operations
| Operation | Idempotent? | Reason |
|---|---|---|
| Set status to "Shipped" | Yes | The final state stays the same on repeat |
| Delete order 501 | Yes | The order stays deleted |
| Add 100 to the balance | No | Every repeat adds again |
| Create a new payment | No | Every repeat creates another payment |
In HTTP, GET, PUT, and DELETE are idempotent by design. POST is not, so POST requests need extra protection.
Why Duplicates Happen
- A client times out and retries while the first request still runs.
- A user taps a button twice.
- A message broker delivers a message more than once.
- A retry policy in a gateway or service mesh replays the call.
The Idempotency Key Technique
The client generates a unique key for each business action and sends it with the request. The server remembers every key it has processed along with the stored result.
Client Server |-- POST /payments | | Idempotency-Key: abc-123 -----> | key unknown: process, save result |<---------- 201 Created ---------- | | (reply lost on the network) | |-- POST /payments | | Idempotency-Key: abc-123 -----> | key known: return saved result |<---------- 201 Created ---------- | (no second charge)
Server Steps
- Read the key from the request header.
- Look up the key in a store such as a database table or cache.
- Return the saved response when the key exists.
- Process the request and save the response with the key when the key is new.
Handling Two Simultaneous Requests
Two copies of the same request can arrive at the same instant. A unique database constraint on the key lets only one insert succeed. The second request waits or receives a "request in progress" reply.
Idempotent Message Consumers
Brokers with at-least-once delivery send duplicates now and then. A consumer keeps a table of processed message ids. Before handling a message, the consumer checks the table and skips known ids.
Message arrives: id = m-77
Is m-77 in processed_messages?
yes --> skip and acknowledge
no --> do the work, store m-77, acknowledge
Run the work and the id insert inside one database transaction so a crash cannot leave them out of step.
Choosing Keys and Expiry
- Use random identifiers such as UUIDs generated on the client.
- Tie one key to one logical action, never to a whole session.
- Keep keys for a limited period, such as 24 hours, to control storage.
- Reject a reused key that arrives with different request content.
Example: Safe Money Transfer
A transfer request carries the key T-9001. The server debits the sender, credits the receiver, and stores the result under T-9001. A repeated request with the same key returns the stored confirmation. Both accounts show a single transfer, and the customer sees a calm success message and no double charge.
Key Takeaways
Idempotency makes retries safe. Use idempotency keys for create-style requests, track processed message ids in consumers, and enforce uniqueness in the database.
