Backend & APIs

An Idempotency Key Is the Difference Between a Retry and a Duplicate Order

Key takeaway: Network failures make it impossible for a client to know whether a request that timed out actually completed, and an idempotency key lets the server recognise a retry of the same logical operation and return the original result instead of executing it a second time.

The Problem a Retry Creates

A client sends a request to create an order, the request times out before the client receives a response, and the client retries. The server may have processed the first request successfully and simply lost the response on the way back, or it may never have received the first request at all. The client cannot tell which, and if it retries without any mechanism to deduplicate, the server may create the order twice.

This is not a rare edge case — it is the normal consequence of how networks and timeouts work, and it is exactly why operations that create or mutate resources need a way for the server to recognise that two requests are actually the same logical operation rather than two distinct ones.

How an Idempotency Key Works

The client generates a unique key for each logical operation — a UUID is the typical choice — and sends it with the request, usually in a header. The server stores the key along with the result of the operation the first time it sees it, and on any subsequent request carrying the same key, it returns the stored result instead of executing the operation again.

Request Server behaviour
First request with key K Executes the operation, stores key K and the result
Retry with the same key K Returns the stored result, does not execute again
New request with a different key Executes as a new operation

This makes the operation idempotent from the client’s perspective — retrying it is safe, because the server will not create a duplicate regardless of how many times the retry arrives, as long as it carries the same key.

The Key Requirements for This to Work

The key must be generated by the client and be unique per logical operation, and the same key must be reused for all retries of that same operation — a client that generates a fresh key on every retry defeats the entire mechanism, since the server sees each retry as a new operation.

The server must store the key and result durably, and the check for an existing key must be atomic with respect to concurrent requests carrying the same key — two simultaneous requests with the same key must not both execute the operation, which typically requires a unique constraint on the key in the database or an equivalent atomic mechanism, so that only one of the concurrent requests actually performs the work and the other receives the stored result.

Where This Matters Most

Idempotency keys matter most for operations that create or change state and that clients are likely to retry — payment processing, order creation, any operation with a real-world consequence if executed twice. Read operations do not need them, since reading twice is harmless, and operations that are naturally idempotent by design, such as setting a value to a specific state, may not need an explicit key if the operation itself is safe to repeat.

The Bottom Line

Use an idempotency key for any client-initiated operation that creates or mutates state and is likely to be retried after a timeout, since without one the server cannot distinguish a retry from a new operation and may execute the same operation twice. Generate the key client-side, reuse it across all retries of the same operation, and store it durably with an atomic uniqueness guarantee so concurrent retries cannot both execute.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button