Picture a customer tapping send on a payment, the app freezes for a second, and out of habit they tap it again. If your backend is not built to handle that gracefully, the customer just paid twice, and now you have a support ticket, a refund to process, and a customer who no longer trusts your app with their money.

Most developers know the standard fix for this. You generate a unique id for the request, attach it to the call, and check whether that id has already been processed before doing anything. This works well and solves the immediate problem of a single call being retried.

But there is a second, quieter version of this problem that catches a lot of backends off guard. What happens when the same logical transaction shows up again, not as an obvious retry, but days or weeks later, from a different source, with slightly different metadata. A transaction id check alone will not save you here, because in this case the ids might not even match.

Retry safe idempotency, the version most people already know

The common approach is to generate an idempotency key on the client side, send it with the request, and store it once the request has been processed. If the same key arrives again, you know it is a retry of the same request, not a new one.