Retry with exponential backoff
- : the base delay, often one second.
- : the multiplier, conventionally 2.
- : the attempt number.
Waiting a constant interval between retries synchronises every client into the same rhythm, which is what turns a brief overload into a sustained one.
Full jitter spreads the retries across the whole window, and it is measurably better than backoff alone at clearing a queue.
Five attempts covers about half a minute, which is long enough for a transient fault and short enough that a caller is still waiting.
Not every error should be retried
Retry on 429, 500, 502, 503, 504 and on timeouts.
Rate limits and server faults are transient by definition, and the same request will probably succeed later.
Do not retry 400, 401, 403, 404 or 422.
A malformed request, a bad key or a missing resource will fail identically every time, and retrying is a way to turn one error into five.
Some servers send a Retry-After header.
When the server states a delay, that number wins over any local formula, because it is the only party that knows when it will be ready.
The agent case is different
A tool error inside an agent loop is not only an operational failure. It is information the model can act on.
- Catch the exception at the tool boundary rather than letting it kill the loop.
- Return it as an observation, with the message and enough context to act on.
- Let the model decide: fix the arguments, try another tool, or report that it cannot proceed.
- Count consecutive failures of the same tool.
- After a small number, stop offering that path and say so in the context.
Here an error is an observation, not an exception.
That reframing is what separates an agent that recovers from one that crashes, and it costs a try block.
Guarding against the repeat
A model that receives the same error twice often tries the same call a third time, since its context now contains two examples of that call being the thing to do.
The fix is to state it explicitly in the returned observation: this exact call has already failed twice, try something different.
The usual guard is a circuit breaker: it opens after failures and tries again after a pause.
For an external service, a breaker stops the calls entirely for a period, which protects both the caller's budget and the service's recovery.
Idempotency, or retries make it worse
Retrying a payment can charge the customer twice.
A retry after a timeout is dangerous whenever the first attempt may have succeeded before the response was lost.
The fix is an idempotency key: the same key always has the same effect.
Any tool with a side effect needs a key the server can deduplicate on, or the retry logic is a mechanism for doing things twice.
Read-only tools are safe to retry freely, which is a good reason to separate the two kinds in an agent's tool list rather than treating them alike.