Silence does not prove nothing happened
Imagine an app sends an order, the server saves it, and the response gets lost in the network. The client sees an error and tries again. If each attempt creates an order, a communication failure becomes a business problem. That is why “keep retrying until it works” is not enough.
A timeout limits how long the caller waits; it does not automatically undo work already performed by the remote service. The interface should distinguish confirmed failure from an unknown outcome. When needed, allow the operation’s status to be checked before creating another.
Give the operation an identity
An idempotency key identifies the same intent across attempts. The server must store and recognize it, associating it with the result. Generating a different key for each retry defeats the purpose. Concurrent requests must also be handled so two executions are not accepted as new.
This does not mean ignoring differences. Reusing a key with a different amount or recipient must be handled explicitly by the API. Define how long the key is retained and what happens afterward. The guarantee depends on the contract and implementation, not the header’s name.
Fewer retries can make recovery better
For transient failures, use bounded retries with increasing delays. Random variation, called jitter, helps prevent everyone from retrying at exactly the same time. Do not apply the same logic to invalid credentials or rejected data: waiting rarely fixes those problems. Respect the downstream service’s guidance and limits.
Watch the layers too: uncoordinated retries in the app, library, and intermediary can multiply load. Decide where retries are controlled and track unknown outcomes. User messages should explain the next available step without claiming an operation failed when its outcome is still unknown.
Test the response that never arrives
In a test environment, simulate a lost response after saving an operation. Retry with the same key and confirm there is only one result. Then test simultaneous attempts and a reused key with different data. Document expected behavior first; success means preserving the user’s intent.
Sources & further reading
- AWS — Retry with backoff pattern ↗
- AWS Builders’ Library — Timeouts, retries, and backoff with jitter ↗
Sources accessed October 24, 2026. Numerical examples and scenarios are illustrative.
Ready to put this knowledge into practice?
We can work together on your team’s challenge or your next project.
Talk to Calembe ↗