Retry with BackoffLoading saved progress…

Retry with Backoff

Retrying a failed request is common; retrying it well is the trick. Exponential backoff re-runs a failing async function with a delay that grows after each attempt — wait 100ms, then 200ms, then 400ms — so a struggling server gets breathing room instead of a hammering. It's the standard resilience pattern for network calls.

Implement retry(fn, options). Call fn; if it rejects, wait and retry, multiplying the delay by factor each time, up to retries attempts. If it still fails, reject with the last error.

Signature

function retry(fn, options) {
  // options: { retries = 3, delay = 100, factor = 2 }
  // returns a promise that resolves with fn's value, or rejects with the
  // last error after retries are exhausted.
}

Examples

// Retries up to 3 times, waiting 100ms, 200ms, 400ms between attempts:
await retry(() => fetch('/flaky'));
await retry(fetchData, { retries: 5, delay: 50, factor: 2 });
// waits 50, 100, 200, 400, 800 ms between the 5 retries

Notes

  • retries is the retry countafter the first attempt. So retries: 3 means up to 4 total calls (1 + 3).
  • Delay grows by factor — first wait is delay, then delay * factor, then delay * factor², and so on.
  • Resolve on first success — stop retrying the moment fn resolves; return its value.
  • Reject with the last error — after all retries fail, reject with the error from the final attempt.
  • factor of 1 — keeps the delay constant (linear retry); the default 2 doubles it each time.
Loading editor…