Retry failed operations with exponential backoff
Quick Answer
The `retry` utility re-runs an async function up to `maxAttempts` times, waiting `delay * backoff^(attempt-1)` milliseconds between each attempt before re-throwing.
1async function retry<T>(
2 fn: () => Promise<T>,
3 options: {
4 maxAttempts?: number;
5 delay?: number;
6 backoff?: number;
7 } = {}
8): Promise<T> {
9 const { maxAttempts = 3, delay = 1000, backoff = 2 } = options;
10
11 for (let attempt = 1; attempt <= maxAttempts; attempt++) {
12 try {
13 return await fn();
14 } catch (error) {
15 if (attempt === maxAttempts) throw error;
16 const waitTime = delay * Math.pow(backoff, attempt - 1);
17 await new Promise(resolve => setTimeout(resolve, waitTime));
18 }
19 }
20 throw new Error('Max attempts reached');
21}Transient failures are common in distributed systems — a network blip, a rate limit, or a briefly unavailable service. This retry utility re-invokes an async function up to a configurable number of times, waiting progressively longer between attempts using exponential backoff to avoid thundering-herd effects.
Exponential backoff doubles (or multiplies by a factor) the wait time between each retry. It prevents many clients from retrying simultaneously, which would overload a recovering service — known as the thundering herd problem.
This free typescript code snippet for retry with backoff is production-ready and copy-paste friendly. Whether you are building a web app, API, or frontend interface, this advanced-level example will help you implement retry with backoff quickly and correctly.
All snippets in the Snippetly library follow typescript best practices and are tested for real-world use. You can adapt this code to work with React, Vue, Node.js, or any project that uses typescript.
Organise your team's code snippets with Snippetly. Share knowledge and boost productivity across your organisation.