Handle Token Refresh Safely in Concurrent API Calls
Prevent multiple token refreshes when parallel API calls fail — learn how to design a shared promise-based refresh mechanism.
Advertisement
Question
You have multiple API requests that fail with a 401 Unauthorized error at the same time.
How can you ensure only one refresh request runs, while other requests wait for it to complete?
Explanation
This is a race condition in authentication logic.
If each failed request triggers a token refresh independently, you’ll flood your API.
We fix this by sharing one refresh promise globally.
Implementation
let refreshPromise = null;
async function refreshTokenOnce() {
if (!refreshPromise) {
refreshPromise = fetch('/auth/refresh')
.then((res) => res.json())
.finally(() => (refreshPromise = null));
}
return refreshPromise;
}
async function fetchWithAuth(url, options) {
const res = await fetch(url, options);
if (res.status === 401) {
const newToken = await refreshTokenOnce();
return fetch(url, {
...options,
headers: { Authorization: `Bearer ${newToken.accessToken}` },
});
}
return res;
}
Visualization
sequenceDiagram participant A as API Request 1 participant B as API Request 2 participant R as Refresh Token Call A->>R: 401 → Triggers refresh B->>R: Waits for same promise R-->>A: New Token Returned R-->>B: Same Token Used
Summary
✅ Prevents redundant token refresh
✅ Keeps requests synchronized
✅ Works with Axios interceptors or fetch
✅ Real-world production pattern for any token-based app
Why do multiple refresh calls happen?
When parallel API calls get 401s, each tries to refresh the token — unless you share a single refresh promise.
Advertisement
Stay Updated
Get the latest frontend challenges, interview questions and tutorials delivered to your inbox.
Advertisement