Late or lost
A request that never answers is either late or lost, and the two need opposite handling.
You send a request to another system and nothing comes back. Retrying is the obvious move, and most of the time it’s the right one. When it’s wrong, a payment goes out twice.
I learned that on iTRY at Inverter Network. My first recovery pass treated every vanished transaction as failed and retried it, and some of them had already settled. The retry logic did what I told it to. I’d told it the wrong thing.
A request with no answer is late or lost, and from the sender’s side you often can’t tell which. A late one needs you to wait, because sending it again creates a duplicate. A lost one needs you to send it again, because waiting leaves the work stuck.
Make the retry safe
On iTRY, a dropped transaction went back out under its original sequence number, so the network itself could only settle one copy. Separately, JobStash billing works from the other side. Fulfillment keys off the payment provider’s event ID, so a repeated callback does nothing.
Once a retry can’t do damage, you can set short timeouts and retry freely.
Then check the source
A retry doesn’t tell you what happened, so something has to go and read the truth. On iTRY a scheduled sweeper diffed the chain against our records. It was slow, and it’s the part of that system I’d defend first in a design review.
Picture a courier who can’t tell whether a parcel arrived. You don’t want a second parcel. You want them to knock on the door.