Track Request Dispatched Timestamp in Axios

Tracking the exact timestamp when an HTTP request is dispatched using Axios is essential for monitoring network latency, logging, and calculating accurate round-trip times (RTT). By leveraging Axios interceptors, you can attach custom metadata containing a high-precision timestamp to the request configuration object immediately before it is sent over the network. This guide explains how to implement request and response interceptors to capture dispatch timestamps and measure request durations effectively.

Using Request Interceptors to Record Timestamps

Axios does not capture timestamps natively, but its interceptor pipeline allows you to modify the request configuration right before the dispatch occurs. You can assign a custom property—such as metadata—to the config object.

Here is how to set up an interceptor to record the exact dispatch time:

import axios from 'axios';

// Create an Axios instance
const apiClient = axios.create({
  baseURL: 'https://api.example.com',
});

// Add a request interceptor
apiClient.interceptors.request.use(
  (config) => {
    // Attach dispatch timestamp to the config object
    config.metadata = {
      startTime: performance.now(),       // High-resolution relative timestamp
      dispatchedAt: new Date().toISOString() // Absolute ISO timestamp
    };
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

Measuring Request Duration in the Response Interceptor

To evaluate the time taken between the dispatch and the response arrival, configure a response interceptor. This interceptor calculates the elapsed duration for both successful and failed requests.

// Add a response interceptor
apiClient.interceptors.response.use(
  (response) => {
    const { startTime, dispatchedAt } = response.config.metadata || {};
    const endTime = performance.now();
    const duration = startTime ? (endTime - startTime).toFixed(2) : null;

    console.log(`[HTTP SUCCESS] ${response.config.method?.toUpperCase()} ${response.config.url}`);
    console.log(`Dispatched at: ${dispatchedAt}`);
    console.log(`Duration: ${duration} ms`);

    // Optionally attach timing data to the response
    response.duration = duration;
    return response;
  },
  (error) => {
    if (error.config && error.config.metadata) {
      const { startTime, dispatchedAt } = error.config.metadata;
      const endTime = performance.now();
      const duration = (endTime - startTime).toFixed(2);

      console.error(`[HTTP ERROR] ${error.config.method?.toUpperCase()} ${error.config.url}`);
      console.error(`Dispatched at: ${dispatchedAt}`);
      console.error(`Duration until failure: ${duration} ms`);

      error.duration = duration;
    }
    return Promise.reject(error);
  }
);

Choosing Between performance.now() and Date.now()

When recording timestamps, choose the method that fits your use case:

By capturing dispatchedAt for auditing and startTime for performance tracking, you maintain full visibility into when an Axios request left the client and how long it took to resolve.