How to Measure Node.js Performance with perf_hooks
This article explores the perf_hooks module in Node.js,
explaining its core purpose, key features, and practical implementation.
You will learn how this built-in module provides high-resolution time
measurements and performance observation tools to help detect
bottlenecks and optimize your Node.js applications.
What is the perf_hooks Module?
The perf_hooks module is a native Node.js API that
allows developers to measure the performance of their applications using
high-resolution timestamps. Based on the Web Performance APIs used in
modern web browsers, perf_hooks provides a consistent and
standardized way to track execution times, garbage collection events,
and event loop delays.
Unlike traditional timing methods like Date.now(), which
rely on the system clock and can be adjusted by the operating system,
perf_hooks utilizes a monotonic clock. This ensures that
time always flows forward and measurements remain accurate, down to
microseconds.
Key Features of perf_hooks
The module provides several APIs that serve different performance-monitoring needs:
performance.now(): Returns a high-resolution millisecond timestamp representing the time elapsed since the Node.js process started.- Performance Markers and Measures: Allows you to set
named milestones (
performance.mark()) and calculate the duration between them (performance.measure()). - PerformanceObserver: A class used to subscribe to specific types of performance events, allowing you to run callback functions when measurements occur.
- Resource Timing: Measures how long it takes to load network resources and modules.
How to Measure Code Execution Time
The most common use case for perf_hooks is measuring the
time it takes to run a specific block of code. This is done using marks
and measures combined with a PerformanceObserver.
const { performance, PerformanceObserver } = require('perf_hooks');
// 1. Create and start a performance observer
const obs = new PerformanceObserver((list) => {
const entries = list.getEntries();
entries.forEach((entry) => {
console.log(`${entry.name}: ${entry.duration.toFixed(4)}ms`);
});
});
obs.observe({ entryTypes: ['measure'], buffered: true });
// 2. Set the start mark
performance.mark('A');
// 3. Run the code block to measure
for (let i = 0; i < 1000000; i++) {
Math.sqrt(i);
}
// 4. Set the end mark
performance.mark('B');
// 5. Measure the distance between mark A and B
performance.measure('Loop execution time', 'A', 'B');Monitoring Internal Node.js Metrics
Beyond custom code execution, perf_hooks can monitor the
internal health of the Node.js runtime.
Garbage Collection Tracking
By setting the entryTypes of a
PerformanceObserver to ['gc'], you can monitor
when the V8 engine triggers garbage collection and how long it pauses
execution. This is crucial for detecting memory leaks and CPU spikes
caused by frequent memory reclamation.
Event Loop Delay
The module provides the monitorEventLoopDelay function,
which measures the latency of the Node.js event loop. If synchronous
operations block the event loop, this delay will spike, indicating that
the application may feel sluggish or unresponsive to incoming
requests.
By integrating perf_hooks into your development and
production monitoring workflows, you can gather high-precision
diagnostics to keep your Node.js applications running efficiently.