Dynamic Axios Timeouts Based on Network Type
This article explores strategies for dynamically adjusting Axios HTTP client timeout thresholds based on the user's current network connection type. By leveraging modern browser APIs like the Network Information API alongside Axios interceptors and event listeners, developers can optimize application responsiveness and prevent premature request cancellations on slow or fluctuating mobile networks.
1. Detecting Connection Speed via the Network Information API
Modern browsers provide the navigator.connection (or
navigator.mozConnection /
navigator.webkitConnection) interface, which exposes
network details such as effectiveType (4g,
3g, 2g, slow-2g) and estimated
round-trip time (rtt).
You can map these connection states to specific timeout thresholds:
const TIMEOUT_CONFIG = {
'slow-2g': 15000,
'2g': 10000,
'3g': 5000,
'4g': 2500,
default: 5000
};
function getDynamicTimeout() {
const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
if (!connection || !connection.effectiveType) {
return TIMEOUT_CONFIG.default;
}
return TIMEOUT_CONFIG[connection.effectiveType] || TIMEOUT_CONFIG.default;
}2. Applying Dynamic Timeouts via Axios Request Interceptors
The most reliable approach to dynamically adjusting timeouts on a per-request basis is using an Axios request interceptor. This ensures that every outgoing request fetches the latest network state immediately before dispatch.
import axios from 'axios';
const apiClient = axios.create();
apiClient.interceptors.request.use((config) => {
// Only override timeout if not explicitly provided in the individual request config
if (!config.timeout) {
config.timeout = getDynamicTimeout();
}
return config;
}, (error) => {
return Promise.reject(error);
});
export default apiClient;3. Listening for Network State Changes Globally
Rather than querying the API per request, you can listen to network change events to update the global Axios client defaults whenever the user shifts between Wi-Fi, 4G, or poorer signals.
import axios from 'axios';
const apiClient = axios.create({
timeout: getDynamicTimeout()
});
const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
if (connection) {
connection.addEventListener('change', () => {
apiClient.defaults.timeout = getDynamicTimeout();
});
}4. Advanced: Combining Latency Metrics (RTT) and Downlink
For more granular control, timeout values can be calculated
dynamically based on real-time latency (rtt) and estimated
bandwidth (downlink in Mbps):
function calculateLatencyBasedTimeout(baseTimeout = 2000) {
const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
if (!connection || !connection.rtt) {
return baseTimeout;
}
// Set timeout to (3 * RTT) + base overhead, bounded between 2s and 20s
const calculated = (connection.rtt * 3) + baseTimeout;
return Math.min(Math.max(calculated, 2000), 20000);
}5. Server-Side Rendering (SSR) and Fallbacks
Because navigator.connection is purely a browser-side
API, ensure defensive checks are in place for Node.js or SSR
environments:
- Always verify that
typeof window !== 'undefined'andnavigator.connectionexists before accessing properties. - Provide a sensible fallback timeout (typically 5000ms–10000ms) for unsupported browsers or non-browser execution contexts.