Axios Memory Allocation in Large File Uploads
This article explores how the Axios HTTP client handles memory
allocation during large multipart file uploads across both Node.js and
browser environments. It examines the underlying mechanisms used to
avoid high RAM usage—such as Node.js streams and browser
Blob objects—while highlighting common configuration
pitfalls that cause memory spikes and practical solutions to maintain
low memory footprints.
Node.js vs. Browser Runtime Architecture
Axios acts as an isomorphic wrapper, meaning its memory management relies entirely on the host environment: Node.js or the browser.
1. Node.js Environment
In Node.js, Axios uses the native http and
https modules. Memory management during a multipart upload
depends directly on whether data is passed as a complete
Buffer or as a ReadableStream.
- Buffer-Based Uploads (High Memory): If a file is
read entirely into memory using
fs.readFileSync()before being appended to aFormDatainstance, the entire file size is allocated directly in the Node.js V8 heap. This can easily trigger anOut of Memory(OOM) crash for files larger than the available heap limit. - Stream-Based Uploads (Low Memory): By utilizing
fs.createReadStream(), the file is read in small, sequential chunks (typically 64 KB by default). Axios pipes this stream into the HTTP request body. Only a tiny fraction of the file resides in the V8 heap at any given moment.
const fs = require('fs');
const axios = require('axios');
const FormData = require('form-data');
const form = new FormData();
form.append('file', fs.createReadStream('/path/to/large-file.zip'));
await axios.post('https://example.com/upload', form, {
headers: form.getHeaders(),
maxBodyLength: Infinity,
maxContentLength: Infinity,
});Stream Backpressure
Axios and the underlying Node.js stream implementation rely on backpressure handling. If the network socket is slower than the disk read rate, Node.js pauses reading from disk until the internal buffer drains, preventing unbounded memory growth.
2. Browser Environment
In browsers, Axios uses the native XMLHttpRequest (XHR)
API.
FileandBlobReferences: Browsers do not load an entire file into the JavaScript heap when selecting it via<input type="file">. Instead, theFileobject is merely a pointer to the file on the underlying operating system's filesystem.- Native Chunking: When a
FileorBlobis appended to a nativeFormDataobject and passed to Axios, the browser’s internal network stack reads and streams the file directly from disk to the network interface in native memory, bypassing the JavaScript engine's garbage collection and heap.
const formData = new FormData();
formData.append('file', fileInputElement.files[0]);
await axios.post('/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
});Critical Axios Settings for Large Uploads
By default, Axios includes safety caps to prevent runaway memory usage from unexpected payload sizes. When handling large files, these settings must be adjusted:
maxBodyLength: Defines the maximum allowed size of the HTTP request body in bytes (default is 10 MB in Node.js). Setting this toInfinityallows large streams without throwing an error before transmission begins.maxContentLength: Defines the maximum allowed size of the HTTP response content. This should also be set toInfinityif the server returns large payloads.
Key Takeaways for Preventing Memory Leaks
- Never convert large files to Base64 or full in-memory strings, as this increases payload size by ~33% and places the entire payload into the active JavaScript heap.
- Always pass streams in Node.js instead of read buffers to maintain a constant, minimal memory footprint regardless of file size.
- Let the browser handle native
Fileobjects rather than reading them viaFileReader.readAsArrayBuffer()before upload.