Skip to main content
Cloud & AI Hub
Browse
Glossary AI Directory Playgrounds Models Prompts Explainers Strategy Matrix Benchmark Decoder

Idempotency Key

A unique client-supplied identifier that lets a server safely de-duplicate retried requests — so a payment or order sent twice (after a timeout) only happens once.

What is an idempotency key?

An idempotency key is a unique identifier a client attaches to a request so that if the same request is sent more than once, the server recognizes the duplicate and processes it only once — returning the original result instead of performing the action again. It’s the standard mechanism for making non-idempotent operations (creating a charge, placing an order, sending a transfer) safe to retry. The client generates a key (typically a UUID) for an operation and sends it (usually in an Idempotency-Key header); the server stores the key with the operation’s result, so a retry carrying the same key gets the stored result rather than a second execution.

The problem it solves: the lost-response trap

The reason idempotency keys exist is a specific, dangerous failure mode in distributed systems. A client sends a request — say, “charge 100."Theserversuccessfullyprocessesit,buttheresponseislostonthewayback(networkdrops,timeout,clientcrashes).Fromtheclientsperspectivetherequestfailed,soitdoesthenatural,correctthing:itretries.Withoutprotection,theserverseesafresh"charge100." The server **successfully processes it**, but the **response is lost** on the way back (network drops, timeout, client crashes). From the client's perspective the request *failed*, so it does the natural, correct thing: it **retries**. Without protection, the server sees a fresh "charge 100” request and charges the customer again — a double charge, duplicate order, or duplicate transfer. This is exactly why you can’t naively retry operations with side effects. The idempotency key breaks the trap: the retry carries the same key as the original, the server looks it up, sees “I already processed this key — here’s the result I computed,” and returns that original result without charging again. The operation becomes safe to send any number of times with the same effect as sending it once, which is what “idempotent” means and what makes retrying side-effectful operations safe.

Implementing it correctly — the details that matter

A correct implementation has several requirements that are easy to get subtly wrong. The server must atomically check-and-record the key (using the database, or a store like Redis) so that two concurrent requests with the same key don’t both slip through the check and execute — this needs a unique constraint or lock, not a naive “check then write” that has a race window. The server should store and return the original response for a duplicate, so the client gets a consistent result, not just a “duplicate” error. Keys need a sensible retention/expiry (long enough to cover all reasonable retries, not forever). The client must reuse the same key for retries of the same logical operation but use a new key for genuinely new operations — reusing a key for a different intended action would wrongly suppress it, and generating a new key on each retry defeats the whole purpose. There’s also the edge case of a request still in-flight when a retry arrives (the first hasn’t finished), which the server must handle (e.g., return a “still processing” signal rather than executing again). Idempotency keys are a best practice in payment and financial APIs specifically because the cost of a double-execution is so high (Stripe, PayPal, and others require/support them), and they pair with the broader resilience toolkit — retries (which they make safe), circuit breakers, and webhooks (whose at-least-once delivery similarly demands idempotent handling). The recurring mistakes: non-atomic key checks that race under concurrency, not returning the stored original response, clients generating a new key per retry (which provides zero protection), and forgetting the in-flight-duplicate case.

What people get wrong

  • Non-atomic key checks — a naive check-then-execute has a race where two concurrent duplicates both run; the check and record must be atomic (unique constraint or lock).
  • Clients generating a new key per retry: retries must reuse the same key for the same logical operation, or the server can’t recognize the duplicate and protection is lost.
  • Ignoring in-flight duplicates and stored responses — the server must handle a retry that arrives before the first finishes, and return the original result for duplicates rather than re-executing.

Primary source: Stripe: Idempotent requests

Historical figures and technical concepts for informational purposes only. Not technical, professional, legal, or financial advice. Sources: Official Documentation.