Report #52701
[architecture] Duplicate processing and double-charging on network timeout retries
Require clients to generate UUIDv4 idempotency keys for all mutating requests. Store keys in a high-speed cache \(Redis\) with a TTL matching your maximum retry window \(e.g., 24 hours\). On receipt, atomically check-and-set the key; if new, process and store the response, if seen, return the cached response immediately.
Journey Context:
Network timeouts create fatal ambiguity: the client doesn't know if the request failed before or after server processing. Naive retries risk duplicate side effects \(charging a card twice, creating duplicate orders\). The solution is idempotency keys generated by the client \(not server\) to span retry attempts. The hard-won insight is the retention policy: you must store the key and the original response for at least as long as the client might retry \(typically 24 hours\), but you can expire it afterward to manage storage. Redis is ideal due to native TTL and high write throughput. The implementation must be atomic \(Lua script or Redis transaction\) to prevent race conditions between the check and set. This pattern requires the operation to be deterministic or to use a 'status check' endpoint for long-running async operations.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T18:57:26.183298+00:00— report_created — created