A bot is running and the connection drops, the exchange goes into maintenance, or the API stops answering for a few seconds. All of that is ordinary. What creates the problem is not the outage; it is not knowing what became of an order sent during it.
The window of uncertainty
When you send an order, three things can have happened, and with a dropped connection you cannot tell which.
The order never reached the exchange. The order arrived and was accepted, but the response never came back. The order arrived, was accepted and filled, and again no response came back.
A timeout does not distinguish between those three. “Request failed” does not mean the order did not go.
The most expensive assumption
The common mistake at this point is to treat the error as a failure and send the order again.
If the first order did fill, the second doubles the position. If the outage lasted a minute and the bot retried every ten seconds, you can come back to a position six times the size you planned.
The reverse exists too. Treating the error as a fill and not resending leaves you with a position you believe is open and which never opened. Both errors come from the same place: handling an unknown state as if it were known.
Client order IDs are the fix
The mechanism that closes this gap is setting the order’s identifier yourself when you send it. Most exchange APIs allow this; the field name varies and the function does not.
Generating the ID yourself buys two things. An order resent with the same ID is rejected by the exchange, so you cannot accidentally send it twice. And when the connection comes back, you can ask about that ID and learn directly what happened.
The ID must not be random; it has to be reproducible. When the bot restarts it should be able to derive the same ID for the same intended order, or there is nothing left to ask about.
The right order on reconnect
The first thing to do when the connection returns is not to send an order. It is to reconcile state. The sequence:
- Ask for open orders. Compare what the exchange sees against what the bot remembers.
- Ask for recent fills. Anything executed during the outage shows up here.
- Ask for balances and positions. Where those three disagree with your computed state, the exchange is right.
- Close the gap. Only at this step does a new order go out.
A bot that does step four before the first three is trusting its own memory, and that memory was not updated during the outage.
Behaving differently by outage length
There is a decision to make as well: should the strategy pick up where it left off?
For a few seconds, yes. For a long outage the situation differs: the bot remembers the world as it was, and the price may have moved a long way. Defining a threshold, and after outages beyond it managing existing positions rather than opening new ones, is a recognisable safe default.
This needs a visible side too. A bot that does not record what it found and what it did after an outage cannot explain an unexpected position two days later. Three things belong in that log: how long the outage lasted, what discrepancy reconciliation found, and which order was sent to close it.



