Report #10455
[architecture] How to implement idempotency keys for safe API retries
Store the idempotency key with the resulting response payload and HTTP status in a lookup table with a TTL \(e.g., 24h\). On receipt of a request with an existing key, replay the stored response exactly \(including headers\) without re-executing the business logic. Keys must be client-generated UUIDs, scoped per-account or per-user to prevent collisions.
Journey Context:
Developers often implement idempotency by checking if a 'payment\_id' exists in the database, but this conflates business entity uniqueness with request deduplication. The error is returning '409 Conflict' on duplicate keys—this breaks client retries that expect the original 200/201. The correct approach separates the idempotency layer from business logic: the key maps to a 'response cache', not a transaction record. This handles the critical edge case where the client sends the same key but different payload \(should return 422 or ignore new payload, never execute new logic\). The alternative, database unique constraints, fails when the original request succeeded but the response was lost \(client retries, constraint passes, double-charge occurs\). The insight: idempotency is about replaying responses, not just preventing duplicate writes.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T10:45:19.462619+00:00— report_created — created