Track Server Response Time in Express.js
Tracking backend response time is one of the most underrated tools for debugging and improving API performance. When your frontend team reports, “The API feels slow,” how do you know if it’s a server issue or a client/network delay?
In this post, I’ll walk you through how to build middleware in Express.js that tracks:
- When a request is received
- When a response is sent
- The total time taken to process the request
This data is then sent back to the client in response headers like X-Request-Start, X-Request-End, and X-Response-Time.
Let’s dive in.
Why This Matters
Imagine you’re working on a team building a REST API for a dashboard. Users are complaining that reports take several seconds to load. Your API logs only show status codes, and external monitoring tools don’t show enough granularity.
By injecting simple timing headers into the response, your team can quickly isolate whether delays are happening inside your backend — or somewhere else.
The Middleware
Here’s the Express.js middleware that captures and injects timing information into response headers:
const express = require('express');
const app = express();
app.use((req, res, next) => {
const startTime = Date.now();
const isoStart = new Date(startTime).toISOString();
const originalWriteHead = res.writeHead;
res.writeHead = function (...args) {
const endTime = Date.now();
const isoEnd = new Date(endTime).toISOString();
const duration = endTime - startTime;
res.setHeader('X-Request-Start', isoStart);
res.setHeader('X-Request-End', isoEnd);
res.setHeader('X-Response-Time', `${duration}ms`);
return originalWriteHead.apply(res, args);
};
next();
});This middleware works globally, so all routes will include the headers.
Sample Routes for Testing
To see this in action, add some test routes:
app.get('/fast', (req, res) => {
res.send('Fast response');
});
app.get('/delayed', (req, res) => {
setTimeout(() => { // Do your things here
res.send('This was delayed');
}, 500);
});Start the server:
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
});Now hit /fast and /delayed with curl -i or a browser extension like Postman.
Expected Response Headers
For a delayed request, you might see something like this:
X-Request-Start: 2025-07-29T12:34:56.001Z
X-Request-End: 2025-07-29T12:34:56.501Z
X-Response-Time: 500msThese headers show exactly how long your server spent processing the request.
Real-World Use Cases
Debugging Latency
By including these headers, frontend developers can determine whether a delay is caused by the backend or the network. No more guesswork.
Client-Side Metrics
In modern frontends using fetch, these headers can be accessed and reported:
fetch('/api/data')
.then(res => {
console.log('Backend processing time:', res.headers.get('X-Response-Time'));
});This makes it easy to build internal performance dashboards or send metrics to a monitoring tool.
Logging and Tracing
You can enhance your backend logs with this data:
res.on('finish', () => {
console.log(`[${req.method}] ${req.originalUrl} took ${res.getHeader('X-Response-Time')}`);
});For production, integrate this with Winston, Bunyan, or a monitoring service like Datadog or Prometheus.
Security and Best Practices
These headers don’t expose sensitive data, but in high-security environments, consider:
- Sending them only in non-production environments
- Scrubbing timestamps if needed
- Whitelisting internal routes to receive them
As with any headers, treat them with the same care you would any telemetry.
Conclusion
Adding custom response timing headers in Express.js is a simple and effective way to gain visibility into your backend performance.
To recap:
- Use middleware to capture the request start time.
- Override
res.writeHead()to inject end time and duration. - Send
X-Request-Start,X-Request-End, andX-Response-Timeto the client.
This lightweight solution will make debugging, monitoring, and collaborating across teams faster and easier.
—
I hope you found this helpful and easy to implement in your own projects.
If you have questions, thoughts, or improvements, feel free to reach out or drop a comment.
Cheers,Happy Coding!!
Sangwin Gawande
https://sangw.in
