If you were to test the execution time of your Node.js code, which timing function would you choose? The first options that typically come to mind are Date.now
or Date.getTime
.
Conclusion First:
In Node.js programs, prioritize process.hrtime
, followed by performance.now
, and lastly Date.now
.
This preference is based on considerations of precision and clock synchronization.
Explanation
Limitations of Date.now
- The precision of the returned time is at the millisecond level (10^-3), which is insufficient for many use cases.
- It is affected by system time and can be influenced by adjustments from other software.
To achieve higher precision and independence from system time, the W3C established the High Resolution Time Level 2 standard. The 6. Monotonic Clock section specifies that standard-compliant implementations must provide a "monotonic" global system clock.
This standard has been implemented in both Node.js and browsers via the performance
object. We can use performance.now
to obtain a timestamp relative to a starting point, with the following features:
- Unlike other time-related functions in JavaScript (e.g.,
Date.now
),performance.now()
returns a floating-point number, achieving microsecond (10^-6) precision. - The time increases at a constant rate and is not affected by system time adjustments (e.g., changes by other software).
- Per the standard definition,
performance.now()
allows for clock drift.
A Brief Note on Clock Drift
Clock drift arises from the concept of clock synchronization, which aims to align multiple independent clocks. In reality, even after synchronization, clocks may drift over time due to slight differences in their ticking rates, leading to varying displayed times.
Is There a More Precise Clock?
Yes, in Node.js, there is the process.hrtime
method:
- Introduced in Node.js v0.7.6, with excellent compatibility (current version is already v22 LTS).
- Provides nanosecond (10^-9) precision.
- Immune to clock drift.
The process.hrtime
method is specifically designed for measuring time intervals.
Note: The browser environment does not support hrtime
, so the best precision achievable in browsers is the microsecond level via performance.now
(subject to implementation differences across browsers).
However, using process.hrtime
requires attention to its usage. The first call returns a time
value, which must be used as an input parameter for subsequent calls:
const NS_PER_SEC = 1e9;
const time = process.hrtime(); // First call, returns the initial `time` variable
// [ 1800216, 25 ]
setTimeout(() => {
const diff = process.hrtime(time); // Use the first returned `time` as input for the second call to calculate the time difference
// [ 1, 552 ]
console.log(`Benchmark took ${diff[0] * NS_PER_SEC + diff[1]} nanoseconds`);
// Benchmark took 1000000552 nanoseconds
}, 1000);
This concludes the main content and naturally leads to the conclusion at the beginning of this section.
Additional Notes
You can also use the hrtime.bigint
method. This is a BigInt-based version of process.hrtime
(BigInt support was introduced in v10.4), which provides the current high-precision actual time.
This method is more convenient than process.hrtime
because it does not require an additional time
input parameter. You can calculate the time difference by simply subtracting the results of two calls:
const start = process.hrtime.bigint();
// 191051479007711n
setTimeout(() => {
const end = process.hrtime.bigint();
// 191052633396993n
console.log(`Benchmark took ${end - start} nanoseconds`);
// Benchmark took 1154389282 nanoseconds
}, 1000);
We are Leapcell, your top choice for deploying Node.js projects to the cloud.
Leapcell is the Next-Gen Serverless Platform for Web Hosting, Async Tasks, and Redis:
Multi-Language Support
- Develop with Node.js, Python, Go, or Rust.
Deploy unlimited projects for free
- pay only for usage — no requests, no charges.
Unbeatable Cost Efficiency
- Pay-as-you-go with no idle charges.
- Example: $25 supports 6.94M requests at a 60ms average response time.
Streamlined Developer Experience
- Intuitive UI for effortless setup.
- Fully automated CI/CD pipelines and GitOps integration.
- Real-time metrics and logging for actionable insights.
Effortless Scalability and High Performance
- Auto-scaling to handle high concurrency with ease.
- Zero operational overhead — just focus on building.
Explore more in the Documentation!
Follow us on X: @LeapcellHQ
Top comments (0)