How to Compress Request Payloads with Axios Gzip

Compressing outgoing HTTP request payloads in Axios significantly reduces network bandwidth usage and speeds up data transfers when sending large datasets to a server. While Axios automatically handles the decompression of response bodies, compressing the request body (such as with gzip) must be handled manually or via interceptors before the request is dispatched, alongside setting the appropriate Content-Encoding header.

Why Compress Request Payloads?

By default, Axios sends request bodies uncompressed. When transmitting large JSON payloads, log batches, or binary data, enabling gzip compression can reduce the payload size by up to 70–90%. For compression to work, the receiving server must be configured to recognize the Content-Encoding: gzip header and decompress the incoming stream or buffer.

Compressing Payloads in Node.js

In a Node.js environment, you can use the built-in zlib module to gzip your request body synchronously or asynchronously before passing it to Axios.

const axios = require('axios');
const zlib = require('zlib');

async function sendGzippedData() {
  const payload = JSON.stringify({
    data: "This is a large payload that needs to be compressed before sending.",
    timestamp: Date.now()
  });

  // Compress the payload using zlib
  const gzippedPayload = zlib.gzipSync(payload);

  try {
    const response = await axios.post('https://api.example.com/data', gzippedPayload, {
      headers: {
        'Content-Type': 'application/json',
        'Content-Encoding': 'gzip'
      }
    });
    console.log('Response:', response.data);
  } catch (error) {
    console.error('Error sending request:', error);
  }
}

sendGzippedData();

Compressing Payloads in the Browser

In browser environments, the native CompressionStream API or a lightweight library like pako can be used to compress data into a gzip format.

Using the native CompressionStream API:

import axios from 'axios';

async function compressString(str) {
  const stream = new Blob([str]).stream();
  const compressedStream = stream.pipeThrough(new CompressionStream('gzip'));
  const response = new Response(compressedStream);
  return await response.arrayBuffer();
}

async function sendBrowserData() {
  const payload = JSON.stringify({ message: "Compressed data from browser" });
  const compressedData = await compressString(payload);

  await axios.post('https://api.example.com/data', compressedData, {
    headers: {
      'Content-Type': 'application/json',
      'Content-Encoding': 'gzip'
    }
  });
}

Automating Compression with Axios Interceptors

To avoid manually compressing payloads for every request, you can configure an Axios request interceptor that automatically compresses payloads exceeding a specific size threshold.

const axios = require('axios');
const zlib = require('zlib');

const apiClient = axios.create({
  baseURL: 'https://api.example.com'
});

apiClient.interceptors.request.use((config) => {
  if (config.data && typeof config.data === 'object' && !(config.data instanceof Buffer)) {
    const jsonString = JSON.stringify(config.data);
    
    // Only compress if payload is larger than 1KB
    if (jsonString.length > 1024) {
      config.data = zlib.gzipSync(jsonString);
      config.headers['Content-Encoding'] = 'gzip';
      config.headers['Content-Type'] = 'application/json';
    }
  }
  return config;
}, (error) => {
  return Promise.reject(error);
});

Server-Side Requirement

For compressed requests to be processed, the server must support gzip decompression on incoming requests. In Node.js frameworks like Express, middleware such as compression or configuring body parsers to accept compressed streams is required:

const express = require('express');
const app = express();

// Express automatically inflates gzipped bodies when using express.json()
app.use(express.json());

app.post('/data', (req, res) => {
  console.log(req.body); // Contains the decompressed JSON object
  res.sendStatus(200);
});