Skip to content

From axios-retry

Who this is for: apps that call axiosRetry(instance, options) and want backoff with jitter, Retry-After, timeouts per attempt and a circuit breaker per host, without touching their call sites.

attachResilience(instance, options) from resilience-pipeline/axios takes the same place as axiosRetry(instance, options): one call per axios instance, interceptors and call sites unchanged, per-request overrides on the request config. The difference is what you get without options: axios-retry retries 3 times with no delay; attachResilience adds a total timeout, a timeout per attempt, exponential backoff with jitter, and a circuit breaker per host. See the axios integration for the full reference.

axios-retry 4 attachResilience
axiosRetry(instance, options) attachResilience(instance, options), returns { eject() }
retries (default 3) retry: { maxRetryAttempts } (default 3). retry: false disables retries
retryCondition (default isNetworkOrIdempotentRequestError) retryOn: status codes, or ({ response, error, attemptNumber }) => boolean
retryDelay (default: no delay, or Retry-After when present) default: exponential from 200 ms with full jitter, Retry-After honoured
retryDelay: axiosRetry.exponentialDelay the default; tune with retry: { delay, maxDelay, useJitter }
retryDelay: axiosRetry.linearDelay() retry: { backoffType: 'linear', delay }
retryDelay: (retryCount, error) => ms retry: { delayGenerator: ({ outcome, attemptNumber }) => ms }
shouldResetTimeout: false (axios timeout covers all retries) totalTimeout (default 30 s)
shouldResetTimeout: true attemptTimeout (default 10 s)
onRetry(retryCount, error, config) retry: { onRetry: (args) => … }; to change the request, onBeforeAttempt(config, context)
onMaxRetryTimesExceeded(error, retryCount) retry: { onRetryExhausted: (args) => … }
validateResponse retryOn with a predicate over response
per request: { 'axios-retry': { retries: 0 } } per request: { resilience: { retries: 0 } }
isNetworkError, isRetryableError, … helpers built into the default retryOn (see below)
not available circuitBreaker (per host), concurrency, retryUnsafeMethods, timeProvider
import axios from 'axios';
import axiosRetry from 'axios-retry';
const api = axios.create({ baseURL: 'https://api.example.com', timeout: 10_000 });
axiosRetry(api, { retries: 3, retryDelay: axiosRetry.exponentialDelay });

Leave axios’ own timeout at 0 and let the pipeline time out: an axios timeout fails the attempt with ECONNABORTED, which is then retried.

axiosRetry(api, {
retries: 5,
retryCondition: (error) =>
axiosRetry.isNetworkOrIdempotentRequestError(error) || error.response?.status === 429,
retryDelay: (retryCount) => retryCount * 1000,
onRetry: (retryCount, error) => log.warn(`retry ${retryCount}: ${error.message}`),
onMaxRetryTimesExceeded: (error) => log.error(`gave up: ${error.message}`),
});

A status list in retryOn replaces the default statuses; network errors and timeouts stay retryable. A function in retryOn decides alone, for errors as well as responses.

await api.get('/report', { 'axios-retry': { retries: 0 } });

Importing resilience-pipeline/axios adds the typed resilience field to AxiosRequestConfig. Fields: retries, retryOn, timeout, attemptTimeout, idempotent.

axiosRetry(api, {
retryCondition: (error) => error.response?.status === 401,
onRetry: async (_count, _error, config) => {
config.headers.Authorization = `Bearer ${await tokens.refresh()}`;
},
});

onBeforeAttempt receives a copy of the config for each attempt and may return a replacement. It is needed because retries happen inside the adapter: request interceptors run once per request, not once per attempt (axios-retry re-sends the request through the instance, so its retries do run the interceptors again).

  • Timeouts are on by default. 30 s for the whole call and 10 s per attempt. A slow endpoint that used to work may now fail with TimeoutRejectedError; raise attemptTimeout / totalTimeout, or set them per request. totalTimeout: Infinity disables the total budget.
  • What is retried. axios-retry’s default retries network errors, and 429 or 5xx responses on GET HEAD OPTIONS PUT DELETE; it doesn’t retry axios’ own timeout (ECONNABORTED). Ours retries network errors (a fixed list of codes such as ECONNRESET, ECONNABORTED, ETIMEDOUT, ERR_NETWORK), attempt timeouts, and 408 429 500 502 503 504, on GET HEAD OPTIONS TRACE PUT DELETE. Other 5xx statuses (501, 505…) are not retried.
  • POST with an Idempotency-Key header is retried automatically. retryUnsafeMethods: true retries every method; resilience: { idempotent: false } forbids retries for one request.
  • Delays. axios-retry waits 0 ms by default (or the Retry-After value); exponentialDelay starts at 200 ms plus up to 20% added randomness. Ours starts at 200 ms with full jitter (anywhere between 0 and the computed delay), and uses Retry-After when the response has one.
  • Custom delayGenerator replaces the Retry-After handling. If you set retry.delayGenerator, read the header yourself or Retry-After is ignored.
  • Callback arguments. axios-retry passes retryCount from 1, the error and the config. onRetry receives { outcome, context, attemptNumber, retryDelay, duration }, with attemptNumber from 0. For a non-2xx status, outcome.error is the AxiosError and outcome.error.response the response.
  • Errors reaching the caller. After the last retry, the caller gets the original AxiosError, as with axios-retry. Rejections by the pipeline (TimeoutRejectedError, BrokenCircuitError, BulkheadRejectedError) are not AxiosErrors.
  • Removal. axios-retry registers interceptors; attachResilience replaces the instance’s adapter. eject() restores the previous adapter. A per-request adapter bypasses the pipeline.
  • Bundled browser code may need getAdapter: axios.getAdapter (see Bundled browser code).
  • Timeouts per attempt and in total, a circuit breaker and an optional concurrency limit per host, Retry-After support.
  • Telemetry for every retry, timeout and breaker transition, exportable to OpenTelemetry or Prometheus.
  • The same engine as createResilientFetch(), so fetch and axios clients behave the same.

Related: axios integration, fetch, Retry, Circuit breaker.