Monitor HTTP Payload Size with Axios Interceptors
Monitoring the size of HTTP requests and responses at runtime is essential for optimizing network performance, diagnosing bandwidth bottlenecks, and enforcing payload limits. This guide demonstrates how to calculate and log the payload sizes of outgoing requests and incoming responses by leveraging Axios interceptors in both browser and Node.js environments.
Why Use Interceptors for Payload Monitoring?
Axios interceptors allow you to hook into the HTTP lifecycle before a request is sent and before a response reaches your application logic. Using interceptors for payload monitoring provides a centralized, non-intrusive way to measure network traffic across all API calls without modifying individual endpoint handlers.
Calculating Payload Size
Because payloads can be strings, JSON objects, FormData,
or binary buffers, size calculations depend on the data type and the
runtime environment:
- Node.js: Use
Buffer.byteLength(data)for strings and buffers. - Browser: Use
new Blob([data]).sizeornew TextEncoder().encode(data).length. - JSON Objects: Serialize objects using
JSON.stringify()before measuring byte length.
Step-by-Step Implementation
1. Create a Helper Function to Measure Size
Create a utility function that safely computes the byte size of various payload types across runtimes:
function getPayloadSize(data) {
if (!data) return 0;
// If already a Buffer (Node.js)
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(data)) {
return data.length;
}
// If a string
if (typeof data === 'string') {
return typeof Buffer !== 'undefined'
? Buffer.byteLength(data, 'utf8')
: new Blob([data]).size;
}
// If a plain JavaScript object
if (typeof data === 'object') {
try {
const serialized = JSON.stringify(data);
return typeof Buffer !== 'undefined'
? Buffer.byteLength(serialized, 'utf8')
: new Blob([serialized]).size;
} catch {
return 0;
}
}
return 0;
}2. Configure the Request Interceptor
The request interceptor intercepts outgoing configuration, calculates the request body size, and records metadata (like timestamps) onto the configuration object:
import axios from 'axios';
const apiClient = axios.create({
baseURL: 'https://api.example.com',
});
apiClient.interceptors.request.use(
(config) => {
const requestSize = getPayloadSize(config.data);
config.metadata = {
startTime: Date.now(),
requestSizeInBytes: requestSize,
};
console.log(`[Request] ${config.method?.toUpperCase()} ${config.url} - Payload Size: ${requestSize} bytes`);
return config;
},
(error) => Promise.reject(error)
);3. Configure the Response Interceptor
The response interceptor measures the incoming response payload. It
first attempts to read the standard Content-Length header.
If the header is missing (such as when
Transfer-Encoding: chunked is used), it calculates the size
from the response body directly:
apiClient.interceptors.response.use(
(response) => {
const contentLength = response.headers['content-length'];
const responseSize = contentLength
? parseInt(contentLength, 10)
: getPayloadSize(response.data);
const duration = Date.now() - (response.config.metadata?.startTime || Date.now());
const requestSize = response.config.metadata?.requestSizeInBytes || 0;
console.log(
`[Response] ${response.status} ${response.config.url} ` +
`(${duration}ms) - Request: ${requestSize} B, Response: ${responseSize} B`
);
return response;
},
(error) => {
if (error.response) {
const errorSize = getPayloadSize(error.response.data);
console.warn(
`[Error Response] ${error.response.status} ${error.config?.url} - Error Payload: ${errorSize} bytes`
);
}
return Promise.reject(error);
}
);
export default apiClient;Best Practices
- Avoid Over-serialization: For large binary streams
or
FormData, avoid callingJSON.stringify(). Instead, inspect headers or rely on stream byte counters. - Enforce Threshold Warnings: Add threshold checks inside interceptors to trigger alerts when a request or response exceeds a specific size (e.g., payloads over 1 MB).
- Integrate APM Tools: Send size metrics directly to Application Performance Monitoring (APM) tools or logging platforms such as Datadog, Prometheus, or CloudWatch for runtime analytics.