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:

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:

  1. You can display an indeterminate loading spinner.
  2. 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