Pluggable retry decisions via retryPolicy
The default retry strategy is retryDelay x 2attempt. Pass a retryPolicy function for smarter behaviour: honouring Retry-After on 429/503, classifying permanent vs transient errors, jitter to avoid thundering herd, or capping at a wall-clock budget. Return a delay in ms, false to abort, or true to fall back to the default.
Function signature:
(attempt, error, ctx) => number | false | true where attempt is the 1-based next try, error is the failure, and
ctx is { task, kind: 'task'|'chunk'|'control', index? }.
Recipe library
// 1. Honor Retry-After on 429/503
retryPolicy: (attempt, err) => err.retryAfter ? err.retryAfter * 1000 : true
// 2. Never retry permanent errors
retryPolicy: (attempt, err) => /HTTP (401|403|404|410|422)/.test(err.message) ? false : true
// 3. Wall-clock budget (5 minutes)
const deadline = Date.now() + 5 * 60_000;
retryPolicy: () => Date.now() > deadline ? false : true
// 4. Jittered exponential (avoid thundering herd)
retryPolicy: (attempt) => {
const base = 1000 * Math.pow(2, attempt - 1);
return base + Math.random() * base * 0.5;
}
// 5. Per-error-class strategy
retryPolicy: (attempt, err, ctx) => {
if (ctx.kind === 'chunk' && /timeout/i.test(err.message)) return 5000; // give chunks more time
if (err.message.startsWith('HTTP 5')) return 1000 * attempt; // linear for 5xx
return true; // exponential default
}Where it's invoked
Called whenever a task or chunk fails and a retry is being considered. Triggered from:
- Task-level retry - full upload retried after a single-strategy failure
- Chunk-level retry - applies to chunked / s3 / azure / gcs strategies on individual chunk PUTs
- Control-plane retry - applies to s3 sign / azure create / gcs initiate / tus session-create network failures
Safety guarantees
- Returned delays are capped at 10 minutes internally - your runaway sleep can't strand a queue.
- The total number of attempts still respects
options.retries. - If your policy throws, the default exponential backoff applies - broken policies don't break uploads.
- Sleeps respect cancel / pause - aborted tasks don't accumulate dead promises.