Clients sometimes retry requests because a network connection fails, a timeout occurs, or the user clicks a button more than once. For operations such as creating an order or initiating a payment, duplicate requests can produce duplicate side effects.
Idempotency keys provide a way to recognize repeated attempts that represent the same logical operation.
Understand Idempotency
An operation is idempotent when repeating it produces the same intended effect as performing it once.
For example, setting an account preference to a specific value can be naturally idempotent. Creating a new payment, however, may generate a second transaction if the server treats every request as new.
An idempotency key gives the server a client-supplied identifier for one logical operation. When a request with that key is repeated, the server can return the stored outcome rather than performing the operation again.
Define the Request Contract
A client might send a unique key in an HTTP header:
POST /api/orders
Idempotency-Key: 7d9f3e4a-9d7b-4a3a-8d30-3a8f4a7a0c12
Content-Type: application/json
The key should be generated for a logical operation and reused when retrying that same operation. A genuinely new order should receive a new key.
The server should also define how long keys remain valid and how it responds when the same key is reused with a different request body.
Store Idempotency Records Reliably
For operations with important side effects, the key and its outcome should be stored in durable storage. A record may include the key, a request fingerprint, processing status, response details, and creation time.
The storage design must prevent two concurrent requests with the same key from both performing the operation. Database uniqueness constraints and carefully designed transactions can help establish this guarantee.
A simplified database design might enforce uniqueness on a combination such as the authenticated client or account and the idempotency key.
Coordinate the Operation and Its Result
A robust implementation must consider failures between recording the request, performing the side effect, and storing the response.
If an order is created in a database, its creation and the idempotency record may be coordinated within one transaction. If the operation involves an external payment provider, the application may need that provider’s idempotency support or a durable workflow that reconciles uncertain outcomes.
Do not assume that storing a key in memory is sufficient. Application restarts and multiple server instances can otherwise allow duplicates.
Validate Repeated Requests
When a key is reused, compare the new request with the original request according to the API contract. If the payload differs, reject the reuse rather than returning an unrelated result.
Also define what happens while the first request is still processing. The server might return a conflict response, wait for the existing operation, or provide a documented in-progress status.
Test Failure and Concurrency Scenarios
Test identical requests sent sequentially, identical requests sent concurrently, retries after timeouts, and requests with conflicting payloads. Confirm that the business side effect occurs no more than once for the logical operation.
Conclusion
Idempotency keys make retryable APIs safer for operations that must not be duplicated. Reliable implementations need durable storage, concurrency protection, clear request matching, and a strategy for recovering from failures across system boundaries.