Retry async operations with jittered backoff
JavaScript
// Retry an async task with exponential backoff, capped delay and jitter.
async function retry(task, { retries = 3, baseDelay = 200, maxDelay = 5000 } = {}) {
let attempt = 0;
for (;;) {
try {
return await task(attempt);
} catch (error) {
if (attempt >= retries) throw error;
const ceiling = Math.min(maxDelay, baseDelay * 2 ** attempt);
await new Promise((resolve) => setTimeout(resolve, Math.random() * ceiling));
attempt += 1;
}
}
}
// Only retry 503 and 429 responses; other status codes reject immediately.
const fetchHealth = () => fetch('/api/health').then((response) => {
if (response.status === 503 || response.status === 429) {
throw new Error(`temporary status ${response.status}`);
}
return response.json();
});
retry(fetchHealth, { retries: 4 }).then(console.log).catch(console.error);