I am working on a solution that makes http requests to different web services, and I need to measure the response times (detailed), I am currently using the "node:https" module, but I would like to know if there is a Library or package that is not " request" since it is deprecated and with axios I have not managed to do it
I leave here an example of the code I use
import https from "node:https";
const NS_PER_SEC = 1e9;
const MS_PER_NS = 1e6;
const timings = {
// use process.hrtime() as it's not a subject of clock drift
startAt: process.hrtime(),
dnsLookupAt: undefined,
tcpConnectionAt: undefined,
tlsHandshakeAt: undefined,
firstByteAt: undefined,
endAt: undefined,
};
let responseBody = "";
const req = https.request(
{
hostname: SERVICE_URL,
port: 443,
path: "/",
method: "GET",
timeout: 5000,
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
Accept: "*/*",
"Accept-Language": "en-US,en;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
},
},
onAnyMessage
);
async function onAnyMessage(res) {
res.once("readable", () => {
timings.firstByteAt = process.hrtime();
});
res.on("data", (chunk) => {
responseBody += chunk;
});
res.on("end", () => {
timings.endAt = process.hrtime();
console.log(responseBody);
console.log(getTimings(timings));
});
}
function getTimings(eventTimes) {
return {
// There is no DNS lookup with IP address
dnsLookup:
eventTimes.dnsLookupAt !== undefined
? getHrTimeDurationInMs(eventTimes.startAt, eventTimes.dnsLookupAt)
: undefined,
tcpConnection: getHrTimeDurationInMs(
eventTimes.dnsLookupAt || eventTimes.startAt,
eventTimes.tcpConnectionAt
),
// There is no TLS handshake without https
tlsHandshake:
eventTimes.tlsHandshakeAt !== undefined
? getHrTimeDurationInMs(
eventTimes.tcpConnectionAt,
eventTimes.tlsHandshakeAt
)
: undefined,
firstByte: getHrTimeDurationInMs(
eventTimes.tlsHandshakeAt || eventTimes.tcpConnectionAt,
eventTimes.firstByteAt
),
contentTransfer: getHrTimeDurationInMs(
eventTimes.firstByteAt,
eventTimes.endAt
),
total: getHrTimeDurationInMs(eventTimes.startAt, eventTimes.endAt),
};
}
/**
* Get duration in milliseconds from process.hrtime()
* @function getHrTimeDurationInMs
* @param {Array} startTime - [seconds, nanoseconds]
* @param {Array} endTime - [seconds, nanoseconds]
* @return {Number} durationInMs
*/
function getHrTimeDurationInMs(startTime, endTime) {
const secondDiff = endTime[0] - startTime[0];
const nanoSecondDiff = endTime[1] - startTime[1];
const diffInNanoSecond = secondDiff * NS_PER_SEC + nanoSecondDiff;
return diffInNanoSecond / MS_PER_NS;
}
req.on("socket", (socket) => {
socket.on("lookup", () => {
timings.dnsLookupAt = process.hrtime();
});
socket.on("connect", () => {
timings.tcpConnectionAt = process.hrtime();
});
socket.on("secureConnect", () => {
timings.tlsHandshakeAt = process.hrtime();
});
});
req.on("error", (err) => {
console.log(err);
});
req.end();
2
Answers
got
provides timings:Result:
To measure detailed HTTP response timings in Node.js, your current implementation with the node:https module is well-structured. If you’d prefer to simplify or enhance your implementation without reinventing the wheel, there are libraries specifically designed for this purpose. Here’s a guide and some recommendations:
Got
got is a modern, powerful HTTP request library with built-in timing support.
Example:
Undici
undici is a fast and lightweight HTTP/1.1 client developed by the Node.js team. It provides a raw interface but supports detailed timing.
Example:
Manual Approach (Enhancing Your Code)
If you want to stick with node:https but enhance your code:
Use Events for Timing: You’re already doing this well with process.hrtime.
Integrate a Monitoring Library: Use perf_hooks for even more granular timing.
Enhanced Code Example:
For most cases, got is ideal due to its ease of use and built-in automatic timing. undici offers excellent performance and advanced control for low-level needs, while https provides maximum flexibility but requires manual implementation of features like timing.