Skip to content
← Dist
tsretry.tstypescriptreliability

Retry with jittered backoff

Tiny async retry helper with exponential backoff and full jitter.

Shareable utility — no framework deps. Caps delay and uses full jitter so concurrent callers don’t stampede.

export type RetryOptions = {
  retries?: number
  baseMs?: number
  maxMs?: number
  shouldRetry?: (error: unknown) => boolean
}

export async function retry<T>(
  fn: () => Promise<T>,
  {
    retries = 4,
    baseMs = 200,
    maxMs = 8_000,
    shouldRetry = () => true,
  }: RetryOptions = {},
): Promise<T> {
  let attempt = 0
  for (;;) {
    try {
      return await fn()
    } catch (error) {
      if (attempt >= retries || !shouldRetry(error)) throw error
      const exp = Math.min(maxMs, baseMs * 2 ** attempt)
      const delay = Math.floor(Math.random() * exp)
      attempt += 1
      await new Promise((r) => setTimeout(r, delay))
    }
  }
}