October 12, 2026 · 3 min read · Yunus Emre Vurgun

API Retries: Backoff, Deadlines, and Idempotency

http · api · reliability
In this guide
  1. Separate reads from ambiguous writes
  2. Back off inside a deadline
  3. Test the event you hope never happens
  4. Reference tables to keep nearby
  5. Primary sources

A failed request does not necessarily mean a failed operation. A server may commit a write and lose the connection before the client receives its response. Retrying that write can create a duplicate. A reliable client therefore needs an operation policy, not just a loop around fetch.

Start by assigning a total time budget, a maximum number of attempts, and a list of failures worth retrying. Keep a single retry owner where practical. If a browser, gateway, SDK, and application each retry independently, their attempts multiply and can turn a small outage into a traffic spike.

Separate reads from ambiguous writes

A read-only GET is usually a reasonable candidate for a bounded retry. A timed-out POST needs more information. If the server supports an idempotency contract, reuse the same operation key and request body for every attempt. The server must associate that key with the committed effect; inventing a header on the client does not create that guarantee.

For an order submission, persist the operation identifier before sending. If the response is lost, query the operation’s state or repeat it under the documented contract. If neither is supported, expose an uncertain outcome and reconcile it. Reporting a definite failure when the order actually exists creates a second problem for the user.

Back off inside a deadline

delay = random(0, min(cap, base * 2 ** attempt))
remaining = deadline - monotonic_now()
retry only if delay + next_attempt_budget < remaining

This is a policy sketch, not a universal production implementation. A real client also needs cancellation, an attempt timeout, a cap, and sensible handling of Retry-After. When the server asks for a longer wait than the remaining budget allows, stop rather than sleep past the caller’s deadline. Randomized delay helps clients avoid returning in lockstep.

Do not retry an unchanged validation failure. A 400 usually needs corrected input; a 403 needs a permission decision. Even a 502 may follow a write that reached the upstream, so retain the operation’s idempotency rule when classifying transient responses.

Test the event you hope never happens

Make the server commit an operation and then drop the response. Send a duplicate delivery. Cancel while a retry is waiting. Return a Retry-After value beyond the deadline. Check that the user sees a truthful result and the business effect occurs only as intended. Log attempt number and operation ID without logging credentials or private payloads.

Reference tables to keep nearby

Primary sources

These are the specifications and project documentation behind the examples. Check the relevant implementation and version before applying a pattern.

Reference data for this guide

Search the library

Search by a topic, title, or keyword.

Start with a collection

Browse all 205 datasets