Platform Architecture1 min read
Idempotency keys: implementation patterns
Every payment API documents idempotency keys. Every payment platform gets some of the details wrong. A pattern guide.
Idempotency keys are one of those primitives everyone has and no one implements the same way. The specification is simple. The implementation choices ripple through the whole platform.
Written May 2026 from a review of internal APIs.
The core contract
A caller submits the same request with the same idempotency key twice. The receiver either:
- Processes the request the first time and returns the cached response on subsequent calls.
- Recognizes the key is in-flight and either waits or returns "still processing".
- Detects a request that reuses the key with different payload and rejects it.
That last case — same key, different payload — is where implementations vary most.
The design choices
- Key format. UUID v4, ULID, or caller-supplied. Prefer client-supplied for retry-ability; enforce a format.
- Payload hash inclusion. Store a hash of the request body alongside the key. Reject subsequent calls that reuse the key with a different payload.
- Retention. How long is a key valid? 24 hours is a common default. Longer for higher-value operations.
- Cache location. Distributed cache (Redis) for fast lookup, backed by durable storage for the response. The cache alone is not enough.
The mistakes to avoid
- Not persisting the response. The key is in the cache; the response is only in memory. A restart loses both.
- Idempotency scoped per-server, not per-service. A retry that hits a different server than the original is not caught.
- Same-key-different-payload treated as success. The caller intended one operation; the receiver processed two.
- Idempotency at the wrong layer. The auth layer is idempotent; the downstream fraud check is not. The overall operation isn't idempotent.
Idempotency is one of those areas where doing it once, well, at the right layer, saves years of duplicate-transaction incidents.