All templates
Flowchart template

Idempotency key verification flow

Detect duplicate requests and return cached results safely.

Every distributed system has network failures, and network failures cause retries. Without idempotency, a retry that succeeds looks like a duplicate request — you charge the customer twice, create two orders, post two messages. This template shows the server-side flow: check the cache for the idempotency key first. If found, return the cached result. If not, process the request, cache the result with a TTL, and return it. On the next retry, the key is already there, and you return the cached result without re-executing the business logic.

When to use this template

  • Payment and billing APIs — the classic case. Payments MUST be idempotent or you'll process duplicate charges. Build idempotency into every payment endpoint from day one.
  • Any critical write operation — order creation, fund transfers, account provisioning. Anything that happens once and cannot be repeated safely.
  • Designing retry strategies — show your team how idempotency keys work before writing retry logic. With idempotency in place, simple exponential backoff works safely.

How to adapt it

The core pattern stays the same, but tailor the details to your system:

  • Cache implementation — replace the abstract cache with your real store: Redis, DynamoDB, an in-memory map. If using Redis, add TTL expiration; if using a database, add a scheduled cleanup job.
  • Signature/request body validation — document what you sign. Include method, path, and body? Just the body? Hash with a secret or just string-compare? Spell it out so clients can implement matching logic on their side.
  • Error caching strategy — decide whether you cache 4xx errors (bad input) or only 2xx (success). Either way, document it so clients understand what they'll get on a retry.

Visual edits regenerate clean Mermaid code, so you can refine the states and transitions without touching the syntax.

Mermaid code

Copy it anywhere Mermaid is supported — GitHub, Notion, or your docs.

flowchart TD
    A[Request arrives with idempotency key] --> B{Key found in cache?}
    B -->|Yes| C[Return cached response]
    B -->|No| D{Request signature matches stored?}
    D -->|Yes| C
    D -->|No| E[Process request]
    E --> F[Store result in cache]
    F --> G[Set expiration TTL]
    G --> H[Return response]
    C --> H

Frequently asked questions

What is an idempotency key and why does it matter?
An idempotency key is a unique identifier the client sends with a request (usually in a header like Idempotency-Key) that lets the server recognize retries of the same request. If the client resends a payment request due to a network timeout, your server can return the original response instead of processing the payment twice. Without it, retries cause duplicate transactions.
What happens if the client sends the same key with a different request body?
A signature mismatch means either the client changed the request (in which case it's a new operation and needs a new key) or there's a client bug. Your API should return an error: 'this key was already used with different parameters'. This forces clients to generate new keys for legitimately different operations.
How long should I keep idempotency cache entries?
Stripe and similar payment processors cache keys for 24 hours. For internal APIs, TTLs of 15 minutes to 1 hour are common — long enough to cover retry windows and cascading failures. Use a time-based or LRU cache in Redis or similar. Document your TTL clearly so clients know when a key expires.
Do I need to cache successful results and failures differently?
Cache both. If the original request returned a 400 (bad input), store that error response and return it for retries. This prevents accidentally processing the request successfully on a later retry when the client 'fixes' their input — consistency matters more than correctness-of-the-moment. Some teams cache only successes and re-process failures; know your policy and document it.

Related templates