Report #38910
[architecture] Idempotency Keys: How do I prevent duplicate charges or writes when clients retry requests?
Require clients to generate a unique Idempotency-Key header \(UUID v4\) for all mutation requests \(POST, PATCH, DELETE\). Store the key and the serialized response in a lookup table within the same transaction as the business logic, with a TTL of 24\+ hours. On duplicate key detection within the window, return the stored response without re-executing business logic.
Journey Context:
Network timeouts cause clients to retry, leading to double-charging or inventory corruption. Simply checking 'does this record exist' fails for create-then-update flows or when partial failures leave side effects \(emails sent, webhooks fired\). The idempotency key acts as a deterministic write-skipping cache. Critical mistakes: using the key as the database primary key \(fails if the business logic generates side effects outside the main table\), not scoping keys per-user \(allows cross-user collisions\), or not TTLing keys \(unbounded storage growth\). Stripe's implementation is canonical: keys are client-generated, 24h retention, and the locked response includes the original HTTP status code and body.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T19:47:14.709054+00:00— report_created — created