JAVASCRIPT
Handling API Rate Limits with Exponential Backoff
Implement a robust strategy for handling API rate limits and transient errors using exponential backoff with jitter, significantly improving the reliability of your API integrations.
async function fetchWithRetry(url, options = {}, retries = 5, delay = 1000) {
try {
const response = await fetch(url, options);
if (response.status === 429 || response.status >= 500) {
if (retries > 0) {
const retryAfter = response.headers.get('Retry-After');
const actualDelay = retryAfter ? parseInt(retryAfter) * 1000 : delay;
// Add jitter (randomness) to delay to prevent thundering herd problem
const jitter = Math.random() * actualDelay * 0.5; // Up to 50% of delay
const nextDelay = Math.min(actualDelay * 2, 60000) + jitter; // Max 60s delay
console.warn(`Rate limited or server error (${response.status}). Retrying in ${Math.round(nextDelay / 1000)}s...`);
await new Promise(resolve => setTimeout(resolve, nextDelay));
return fetchWithRetry(url, options, retries - 1, nextDelay);
} else {
throw new Error(`Max retries exceeded for URL: ${url}`);
}
}
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json(); // Or response.text() depending on API
} catch (error) {
console.error("Error in fetchWithRetry:", error);
throw error;
}
}
// Example usage:
// fetchWithRetry('https://api.example.com/expensive-operation', { method: 'GET' })
// .then(data => console.log('Data after potential retries:', data))
// .catch(error => console.error('Failed after retries:', error));
How it works: This advanced snippet provides a function `fetchWithRetry` that automatically retries API requests when encountering rate limit (HTTP 429) or server errors (HTTP 5xx). It implements an exponential backoff strategy, increasing the delay between retries, and also incorporates 'jitter' (randomness) to prevent multiple clients from retrying simultaneously, which could overload the server. It respects the `Retry-After` header if provided by the API.