DevOps Glossary

Idempotency Key

An idempotency key is a unique API request token that lets services retry operations without duplicate writes or charges.

Idempotency Key is a unique value sent with an API request so the server can safely recognize retries of the same operation and avoid duplicate side effects, such as creating two orders, charging a card twice, or provisioning the same resource more than once.

In practical terms, an idempotency key lets clients retry requests after timeouts, network failures, or unclear responses without guessing whether the original request succeeded.

What an idempotency key does

An idempotency key helps make unsafe operations safer to retry. This is most common with HTTP methods such as POST and sometimes PATCH, where repeating the same request can change state more than once.

  • Prevents duplicate writes: The server stores the first result for a given key and returns that result for matching retries.
  • Supports reliable retries: Clients can retry after a timeout instead of failing the workflow or creating custom reconciliation logic.
  • Protects user-facing actions: It reduces duplicate payments, orders, tickets, account creations, and deployment actions.
  • Improves distributed system behavior: It handles common failure cases where the client does not know if the server completed the operation.

How it works

A client generates a unique key for one logical operation, then sends it with the request. APIs often accept the key in a header such as Idempotency-Key, though some systems use a request field instead.

  1. The client creates a unique key, often a UUID such as 7d9f4c20-8b2f-4a4e-9d7d-25a7c2a4f7f1.
  2. The client sends the request with that key.
  3. The server checks whether it has already processed a request with the same key.
  4. If the key is new, the server performs the operation and stores the result with the key.
  5. If the same key appears again with the same request, the server returns the stored result instead of running the operation again.

For example, a payment API might receive a charge request with an idempotency key. If the client times out and retries, the API can return the original charge response instead of creating a second charge.

Common use cases

  • Payment processing: Avoid charging a customer twice when a checkout request is retried.
  • Order creation: Prevent duplicate orders after a mobile app loses connectivity.
  • Resource provisioning: Avoid creating duplicate cloud resources, projects, tenants, or environments.
  • CI/CD and deployment APIs: Prevent duplicate release, rollback, or job-trigger actions.
  • Event-driven systems: Deduplicate command handling when messages are delivered more than once.
  • Webhook consumers: Process repeated webhook deliveries safely when providers retry failed deliveries.

Key design details

  • Key scope: Define where a key is unique. Common scopes include per user, per account, per endpoint, or global.
  • Request matching: Decide whether the same key must include the same request body, method, path, and tenant. Many APIs reject a reused key if the payload differs.
  • Storage: Store keys in a durable datastore such as PostgreSQL, Redis, DynamoDB, or another system that supports atomic writes.
  • TTL: Keep keys long enough to cover realistic retries. Common retention windows range from a few hours to several days, depending on the workflow.
  • Response caching: Store the status code and response body when returning the same result matters to clients.
  • Concurrency control: Handle simultaneous requests with the same key using unique constraints, locks, or conditional writes.

Simple example

A frontend sends a request to create an order:

POST /orders
Idempotency-Key: 2f7b6f82-4d0e-4c0e-9f55-6a3a0c2b118a

{
  "cart_id": "cart_123",
  "customer_id": "cust_456"
}

The server creates order order_789 and stores the idempotency key with that result. If the client does not receive the response and retries the same request, the server returns the existing order_789 response instead of creating another order.

Idempotency key vs idempotent operation

An idempotent operation naturally produces the same state when repeated. For example, PUT /users/123 with the same full user representation can be idempotent because repeating it sets the same final state.

An idempotency key adds retry safety to operations that may otherwise create new side effects each time they run, such as POST /charges or POST /orders.

Limitations and tradeoffs

  • It does not fix all duplicate causes: The server must apply the key correctly around the actual side effect. Storing the key after the write can still allow duplicates during crashes.
  • It requires state: The service needs storage for keys, request fingerprints, statuses, and responses.
  • It has retention limits: If a retry arrives after the key expires, the server may treat it as a new request.
  • It can hide client bugs: Reusing the same key for separate operations can cause unexpected repeated responses or rejected requests.
  • It needs clear API behavior: Clients should know how long keys are retained and what happens if the same key is sent with a different payload.

Implementation tips

  • Generate a new key for each logical operation, not each HTTP retry.
  • Use high-entropy keys such as UUIDv4 or ULID values.
  • Store a request fingerprint with the key to detect accidental key reuse with different payloads.
  • Use atomic database operations, such as unique constraints or conditional writes, to avoid race conditions.
  • Return the same status code and response body for successful duplicate retries when possible.
  • Document the key retention period and expected client retry behavior.