How to Monitor Download Progress Using Axios
Tracking download progress in Axios allows you to provide real-time
feedback to users during large file transfers. Axios includes a built-in
configuration callback called onDownloadProgress that
receives progress events containing the number of bytes transferred and
the total file size. This guide explains how to configure this callback,
calculate the download percentage, and handle scenarios where the total
file size is unknown.
Using the
onDownloadProgress Callback
To monitor incoming data, pass the onDownloadProgress
function inside the request configuration object. The callback receives
a progressEvent object with details about the current state
of the download.
import axios from 'axios';
axios({
url: 'https://example.com/large-file.zip',
method: 'GET',
responseType: 'blob', // or 'arraybuffer' / 'stream' depending on your platform
onDownloadProgress: (progressEvent) => {
// In Axios v1.x, progress is often directly available as progressEvent.progress (0 to 1)
if (progressEvent.total) {
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
console.log(`Download progress: ${percentCompleted}%`);
} else {
console.log(`Downloaded ${progressEvent.loaded} bytes (total size unknown)`);
}
},
})
.then((response) => {
console.log('Download complete!');
})
.catch((error) => {
console.error('Download error:', error);
});Understanding the Progress Event Object
In recent versions of Axios (v1.x and newer), the
progressEvent provides several helpful properties:
loaded: The total number of bytes transferred so far.total: The total size of the file in bytes, derived from the server'sContent-Lengthheader. This will beundefinedif the server does not supply this header.progress: A decimal value between0and1representing completion ratio (only available whentotalis defined).bytes: The number of bytes transferred in the most recent chunk.estimated: Estimated time remaining in seconds (if calculated by the adapter).rate: Current download speed in bytes per second.
Server
Requirements: The Content-Length Header
For Axios to calculate an exact percentage, the server serving the
file must include the Content-Length header in its HTTP
response. If the server uses chunked transfer encoding
(Transfer-Encoding: chunked) or omits
Content-Length, progressEvent.total will be
undefined.
When total is unavailable:
- You can display an indeterminate loading spinner.
- You can display only the amount of data transferred
(
progressEvent.loaded) formatted in megabytes or kilobytes.
const loadedMB = (progressEvent.loaded / (1024 * 1024)).toFixed(2);
console.log(`Transferred: ${loadedMB} MB`);Browser vs. Node.js Environments
- Browsers: The
onDownloadProgresshandler uses the underlyingXMLHttpRequestprogress event and works out of the box with standard response types likebloborarraybuffer. - Node.js: When working in a Node.js environment, set
responseType: 'stream'. WhileonDownloadProgressworks in modern Axios versions, you can also attach standard Node stream listeners (response.data.on('data', chunk => ...)) to calculate byte totals directly from the stream.