Performance measurement APIs#
Source Code:lib/perf_hooks.js
This module provides an implementation of a subset of the W3CWeb Performance APIs as well as additional APIs forNode.js-specific performance measurements.
Node.js supports the followingWeb Performance APIs:
import { performance,PerformanceObserver }from'node:perf_hooks';const obs =newPerformanceObserver((items) => {console.log(items.getEntries()[0].duration); performance.clearMarks();});obs.observe({type:'measure' });performance.measure('Start to Now');performance.mark('A');doSomeLongRunningProcess(() => { performance.measure('A to Now','A'); performance.mark('B'); performance.measure('A to B','A','B');});const {PerformanceObserver, performance } =require('node:perf_hooks');const obs =newPerformanceObserver((items) => {console.log(items.getEntries()[0].duration);});obs.observe({type:'measure' });performance.measure('Start to Now');performance.mark('A');(asyncfunctiondoSomeLongRunningProcess() {awaitnewPromise((r) =>setTimeout(r,5000)); performance.measure('A to Now','A'); performance.mark('B'); performance.measure('A to B','A','B');})();
perf_hooks.performance#
An object that can be used to collect performance metrics from the currentNode.js instance. It is similar towindow.performance in browsers.
performance.clearMarks([name])#
History
| Version | Changes |
|---|---|
| v19.0.0 | This method must be called with the |
| v8.5.0 | Added in: v8.5.0 |
name<string>
Ifname is not provided, removes allPerformanceMark objects from thePerformance Timeline. Ifname is provided, removes only the named mark.
performance.clearMeasures([name])#
History
| Version | Changes |
|---|---|
| v19.0.0 | This method must be called with the |
| v16.7.0 | Added in: v16.7.0 |
name<string>
Ifname is not provided, removes allPerformanceMeasure objects from thePerformance Timeline. Ifname is provided, removes only the named measure.
performance.clearResourceTimings([name])#
History
| Version | Changes |
|---|---|
| v19.0.0 | This method must be called with the |
| v18.2.0, v16.17.0 | Added in: v18.2.0, v16.17.0 |
name<string>
Ifname is not provided, removes allPerformanceResourceTiming objects fromthe Resource Timeline. Ifname is provided, removes only the named resource.
performance.eventLoopUtilization([utilization1[, utilization2]])#
utilization1<Object> The result of a previous call toeventLoopUtilization().utilization2<Object> The result of a previous call toeventLoopUtilization()prior toutilization1.- Returns:<Object>
TheeventLoopUtilization() method returns an object that contains thecumulative duration of time the event loop has been both idle and active as ahigh resolution milliseconds timer. Theutilization value is the calculatedEvent Loop Utilization (ELU).
If bootstrapping has not yet finished on the main thread the properties havethe value of0. The ELU is immediately available onWorker threads sincebootstrap happens within the event loop.
Bothutilization1 andutilization2 are optional parameters.
Ifutilization1 is passed, then the delta between the current call'sactiveandidle times, as well as the correspondingutilization value arecalculated and returned (similar toprocess.hrtime()).
Ifutilization1 andutilization2 are both passed, then the delta iscalculated between the two arguments. This is a convenience option because,unlikeprocess.hrtime(), calculating the ELU is more complex than asingle subtraction.
ELU is similar to CPU utilization, except that it only measures event loopstatistics and not CPU usage. It represents the percentage of time the eventloop has spent outside the event loop's event provider (e.g.epoll_wait).No other CPU idle time is taken into consideration. The following is an exampleof how a mostly idle process will have a high ELU.
import { eventLoopUtilization }from'node:perf_hooks';import { spawnSync }from'node:child_process';setImmediate(() => {const elu =eventLoopUtilization();spawnSync('sleep', ['5']);console.log(eventLoopUtilization(elu).utilization);});'use strict';const { eventLoopUtilization } =require('node:perf_hooks').performance;const { spawnSync } =require('node:child_process');setImmediate(() => {const elu =eventLoopUtilization();spawnSync('sleep', ['5']);console.log(eventLoopUtilization(elu).utilization);});
Although the CPU is mostly idle while running this script, the value ofutilization is1. This is because the call tochild_process.spawnSync() blocks the event loop from proceeding.
Passing in a user-defined object instead of the result of a previous call toeventLoopUtilization() will lead to undefined behavior. The return valuesare not guaranteed to reflect any correct state of the event loop.
performance.getEntries()#
History
| Version | Changes |
|---|---|
| v19.0.0 | This method must be called with the |
| v16.7.0 | Added in: v16.7.0 |
- Returns:<PerformanceEntry[]>
Returns a list ofPerformanceEntry objects in chronological order withrespect toperformanceEntry.startTime. If you are only interested inperformance entries of certain types or that have certain names, seeperformance.getEntriesByType() andperformance.getEntriesByName().
performance.getEntriesByName(name[, type])#
History
| Version | Changes |
|---|---|
| v19.0.0 | This method must be called with the |
| v16.7.0 | Added in: v16.7.0 |
name<string>type<string>- Returns:<PerformanceEntry[]>
Returns a list ofPerformanceEntry objects in chronological orderwith respect toperformanceEntry.startTime whoseperformanceEntry.name isequal toname, and optionally, whoseperformanceEntry.entryType is equal totype.
performance.getEntriesByType(type)#
History
| Version | Changes |
|---|---|
| v19.0.0 | This method must be called with the |
| v16.7.0 | Added in: v16.7.0 |
type<string>- Returns:<PerformanceEntry[]>
Returns a list ofPerformanceEntry objects in chronological orderwith respect toperformanceEntry.startTime whoseperformanceEntry.entryTypeis equal totype.
performance.mark(name[, options])#
History
| Version | Changes |
|---|---|
| v19.0.0 | This method must be called with the |
| v16.0.0 | Updated to conform to the User Timing Level 3 specification. |
| v8.5.0 | Added in: v8.5.0 |
Creates a newPerformanceMark entry in the Performance Timeline. APerformanceMark is a subclass ofPerformanceEntry whoseperformanceEntry.entryType is always'mark', and whoseperformanceEntry.duration is always0. Performance marks are usedto mark specific significant moments in the Performance Timeline.
The createdPerformanceMark entry is put in the global Performance Timelineand can be queried withperformance.getEntries,performance.getEntriesByName, andperformance.getEntriesByType. When theobservation is performed, the entries should be cleared from the globalPerformance Timeline manually withperformance.clearMarks.
performance.markResourceTiming(timingInfo, requestedUrl, initiatorType, global, cacheMode, bodyInfo, responseStatus[, deliveryType])#
History
| Version | Changes |
|---|---|
| v22.2.0 | Added bodyInfo, responseStatus, and deliveryType arguments. |
| v18.2.0, v16.17.0 | Added in: v18.2.0, v16.17.0 |
timingInfo<Object>Fetch Timing InforequestedUrl<string> The resource urlinitiatorType<string> The initiator name, e.g: 'fetch'global<Object>cacheMode<string> The cache mode must be an empty string ('') or 'local'bodyInfo<Object>Fetch Response Body InforesponseStatus<number> The response's status codedeliveryType<string> The delivery type.Default:''.
This property is an extension by Node.js. It is not available in Web browsers.
Creates a newPerformanceResourceTiming entry in the Resource Timeline. APerformanceResourceTiming is a subclass ofPerformanceEntry whoseperformanceEntry.entryType is always'resource'. Performance resourcesare used to mark moments in the Resource Timeline.
The createdPerformanceMark entry is put in the global Resource Timelineand can be queried withperformance.getEntries,performance.getEntriesByName, andperformance.getEntriesByType. When theobservation is performed, the entries should be cleared from the globalPerformance Timeline manually withperformance.clearResourceTimings.
performance.measure(name[, startMarkOrOptions[, endMark]])#
History
| Version | Changes |
|---|---|
| v19.0.0 | This method must be called with the |
| v16.0.0 | Updated to conform to the User Timing Level 3 specification. |
| v13.13.0, v12.16.3 | Make |
| v8.5.0 | Added in: v8.5.0 |
name<string>startMarkOrOptions<string> |<Object> Optional.detail<any> Additional optional detail to include with the measure.duration<number> Duration between start and end times.end<number> |<string> Timestamp to be used as the end time, or a stringidentifying a previously recorded mark.start<number> |<string> Timestamp to be used as the start time, or a stringidentifying a previously recorded mark.
endMark<string> Optional. Must be omitted ifstartMarkOrOptionsis an<Object>.
Creates a newPerformanceMeasure entry in the Performance Timeline. APerformanceMeasure is a subclass ofPerformanceEntry whoseperformanceEntry.entryType is always'measure', and whoseperformanceEntry.duration measures the number of milliseconds elapsed sincestartMark andendMark.
ThestartMark argument may identify anyexistingPerformanceMark in thePerformance Timeline, ormay identify any of the timestamp propertiesprovided by thePerformanceNodeTiming class. If the namedstartMark doesnot exist, an error is thrown.
The optionalendMark argument must identify anyexistingPerformanceMarkin the Performance Timeline or any of the timestamp properties provided by thePerformanceNodeTiming class.endMark will beperformance.now()if no parameter is passed, otherwise if the namedendMark does not exist, anerror will be thrown.
The createdPerformanceMeasure entry is put in the global Performance Timelineand can be queried withperformance.getEntries,performance.getEntriesByName, andperformance.getEntriesByType. When theobservation is performed, the entries should be cleared from the globalPerformance Timeline manually withperformance.clearMeasures.
performance.nodeTiming#
This property is an extension by Node.js. It is not available in Web browsers.
An instance of thePerformanceNodeTiming class that provides performancemetrics for specific Node.js operational milestones.
performance.now()#
History
| Version | Changes |
|---|---|
| v19.0.0 | This method must be called with the |
| v8.5.0 | Added in: v8.5.0 |
- Returns:<number>
Returns the current high resolution millisecond timestamp, where 0 representsthe start of the currentnode process.
performance.setResourceTimingBufferSize(maxSize)#
History
| Version | Changes |
|---|---|
| v19.0.0 | This method must be called with the |
| v18.8.0 | Added in: v18.8.0 |
Sets the global performance resource timing buffer size to the specified numberof "resource" type performance entry objects.
By default the max buffer size is set to 250.
performance.timeOrigin#
- Type:<number>
ThetimeOrigin specifies the high resolution millisecond timestamp atwhich the currentnode process began, measured in Unix time.
performance.timerify(fn[, options])#
History
| Version | Changes |
|---|---|
| v16.0.0 | Added the histogram option. |
| v16.0.0 | Re-implemented to use pure-JavaScript and the ability to time async functions. |
| v8.5.0 | Added in: v8.5.0 |
fn<Function>options<Object>histogram<RecordableHistogram> A histogram object created usingperf_hooks.createHistogram()that will record runtime durations innanoseconds.
This property is an extension by Node.js. It is not available in Web browsers.
Wraps a function within a new function that measures the running time of thewrapped function. APerformanceObserver must be subscribed to the'function'event type in order for the timing details to be accessed.
import { performance,PerformanceObserver }from'node:perf_hooks';functionsomeFunction() {console.log('hello world');}const wrapped = performance.timerify(someFunction);const obs =newPerformanceObserver((list) => {console.log(list.getEntries()[0].duration); performance.clearMarks(); performance.clearMeasures(); obs.disconnect();});obs.observe({entryTypes: ['function'] });// A performance timeline entry will be createdwrapped();const { performance,PerformanceObserver,} =require('node:perf_hooks');functionsomeFunction() {console.log('hello world');}const wrapped = performance.timerify(someFunction);const obs =newPerformanceObserver((list) => {console.log(list.getEntries()[0].duration); performance.clearMarks(); performance.clearMeasures(); obs.disconnect();});obs.observe({entryTypes: ['function'] });// A performance timeline entry will be createdwrapped();
If the wrapped function returns a promise, a finally handler will be attachedto the promise and the duration will be reported once the finally handler isinvoked.
performance.toJSON()#
History
| Version | Changes |
|---|---|
| v19.0.0 | This method must be called with the |
| v16.1.0 | Added in: v16.1.0 |
An object which is JSON representation of theperformance object. Itis similar towindow.performance.toJSON in browsers.
Event:'resourcetimingbufferfull'#
The'resourcetimingbufferfull' event is fired when the global performanceresource timing buffer is full. Adjust resource timing buffer size withperformance.setResourceTimingBufferSize() or clear the buffer withperformance.clearResourceTimings() in the event listener to allowmore entries to be added to the performance timeline buffer.
Class:PerformanceEntry#
The constructor of this class is not exposed to users directly.
performanceEntry.duration#
History
| Version | Changes |
|---|---|
| v19.0.0 | This property getter must be called with the |
| v8.5.0 | Added in: v8.5.0 |
- Type:<number>
The total number of milliseconds elapsed for this entry. This value will notbe meaningful for all Performance Entry types.
performanceEntry.entryType#
History
| Version | Changes |
|---|---|
| v19.0.0 | This property getter must be called with the |
| v8.5.0 | Added in: v8.5.0 |
- Type:<string>
The type of the performance entry. It may be one of:
'dns'(Node.js only)'function'(Node.js only)'gc'(Node.js only)'http2'(Node.js only)'http'(Node.js only)'mark'(available on the Web)'measure'(available on the Web)'net'(Node.js only)'node'(Node.js only)'resource'(available on the Web)
Class:PerformanceMark#
- Extends:<PerformanceEntry>
Exposes marks created via thePerformance.mark() method.
Class:PerformanceMeasure#
- Extends:<PerformanceEntry>
Exposes measures created via thePerformance.measure() method.
The constructor of this class is not exposed to users directly.
Class:PerformanceNodeEntry#
- Extends:<PerformanceEntry>
This class is an extension by Node.js. It is not available in Web browsers.
Provides detailed Node.js timing data.
The constructor of this class is not exposed to users directly.
performanceNodeEntry.detail#
History
| Version | Changes |
|---|---|
| v19.0.0 | This property getter must be called with the |
| v16.0.0 | Added in: v16.0.0 |
- Type:<any>
Additional detail specific to theentryType.
performanceNodeEntry.flags#
History
| Version | Changes |
|---|---|
| v16.0.0 | Runtime deprecated. Now moved to the detail property when entryType is 'gc'. |
| v13.9.0, v12.17.0 | Added in: v13.9.0, v12.17.0 |
performanceNodeEntry.detail instead.- Type:<number>
WhenperformanceEntry.entryType is equal to'gc', theperformance.flagsproperty contains additional information about garbage collection operation.The value may be one of:
perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_NOperf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_CONSTRUCT_RETAINEDperf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_FORCEDperf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_SYNCHRONOUS_PHANTOM_PROCESSINGperf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_ALL_AVAILABLE_GARBAGEperf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_ALL_EXTERNAL_MEMORYperf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_SCHEDULE_IDLE
performanceNodeEntry.kind#
History
| Version | Changes |
|---|---|
| v16.0.0 | Runtime deprecated. Now moved to the detail property when entryType is 'gc'. |
| v8.5.0 | Added in: v8.5.0 |
performanceNodeEntry.detail instead.- Type:<number>
WhenperformanceEntry.entryType is equal to'gc', theperformance.kindproperty identifies the type of garbage collection operation that occurred.The value may be one of:
perf_hooks.constants.NODE_PERFORMANCE_GC_MAJORperf_hooks.constants.NODE_PERFORMANCE_GC_MINORperf_hooks.constants.NODE_PERFORMANCE_GC_INCREMENTALperf_hooks.constants.NODE_PERFORMANCE_GC_WEAKCB
Garbage Collection ('gc') Details#
WhenperformanceEntry.type is equal to'gc', theperformanceNodeEntry.detail property will be an<Object> with two properties:
kind<number> One of:perf_hooks.constants.NODE_PERFORMANCE_GC_MAJORperf_hooks.constants.NODE_PERFORMANCE_GC_MINORperf_hooks.constants.NODE_PERFORMANCE_GC_INCREMENTALperf_hooks.constants.NODE_PERFORMANCE_GC_WEAKCB
flags<number> One of:perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_NOperf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_CONSTRUCT_RETAINEDperf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_FORCEDperf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_SYNCHRONOUS_PHANTOM_PROCESSINGperf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_ALL_AVAILABLE_GARBAGEperf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_ALL_EXTERNAL_MEMORYperf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_SCHEDULE_IDLE
HTTP ('http') Details#
WhenperformanceEntry.type is equal to'http', theperformanceNodeEntry.detail property will be an<Object> containingadditional information.
IfperformanceEntry.name is equal toHttpClient, thedetailwill contain the following properties:req,res. And thereq propertywill be an<Object> containingmethod,url,headers, theres propertywill be an<Object> containingstatusCode,statusMessage,headers.
IfperformanceEntry.name is equal toHttpRequest, thedetailwill contain the following properties:req,res. And thereq propertywill be an<Object> containingmethod,url,headers, theres propertywill be an<Object> containingstatusCode,statusMessage,headers.
This could add additional memory overhead and should only be used fordiagnostic purposes, not left turned on in production by default.
HTTP/2 ('http2') Details#
WhenperformanceEntry.type is equal to'http2', theperformanceNodeEntry.detail property will be an<Object> containingadditional performance information.
IfperformanceEntry.name is equal toHttp2Stream, thedetailwill contain the following properties:
bytesRead<number> The number ofDATAframe bytes received for thisHttp2Stream.bytesWritten<number> The number ofDATAframe bytes sent for thisHttp2Stream.id<number> The identifier of the associatedHttp2StreamtimeToFirstByte<number> The number of milliseconds elapsed between thePerformanceEntrystartTimeand the reception of the firstDATAframe.timeToFirstByteSent<number> The number of milliseconds elapsed betweenthePerformanceEntrystartTimeand sending of the firstDATAframe.timeToFirstHeader<number> The number of milliseconds elapsed between thePerformanceEntrystartTimeand the reception of the first header.
IfperformanceEntry.name is equal toHttp2Session, thedetail willcontain the following properties:
bytesRead<number> The number of bytes received for thisHttp2Session.bytesWritten<number> The number of bytes sent for thisHttp2Session.framesReceived<number> The number of HTTP/2 frames received by theHttp2Session.framesSent<number> The number of HTTP/2 frames sent by theHttp2Session.maxConcurrentStreams<number> The maximum number of streams concurrentlyopen during the lifetime of theHttp2Session.pingRTT<number> The number of milliseconds elapsed since the transmissionof aPINGframe and the reception of its acknowledgment. Only present ifaPINGframe has been sent on theHttp2Session.streamAverageDuration<number> The average duration (in milliseconds) forallHttp2Streaminstances.streamCount<number> The number ofHttp2Streaminstances processed bytheHttp2Session.type<string> Either'server'or'client'to identify the type ofHttp2Session.
Timerify ('function') Details#
WhenperformanceEntry.type is equal to'function', theperformanceNodeEntry.detail property will be an<Array> listingthe input arguments to the timed function.
Net ('net') Details#
WhenperformanceEntry.type is equal to'net', theperformanceNodeEntry.detail property will be an<Object> containingadditional information.
IfperformanceEntry.name is equal toconnect, thedetailwill contain the following properties:host,port.
DNS ('dns') Details#
WhenperformanceEntry.type is equal to'dns', theperformanceNodeEntry.detail property will be an<Object> containingadditional information.
IfperformanceEntry.name is equal tolookup, thedetailwill contain the following properties:hostname,family,hints,verbatim,addresses.
IfperformanceEntry.name is equal tolookupService, thedetail willcontain the following properties:host,port,hostname,service.
IfperformanceEntry.name is equal toqueryxxx orgetHostByAddr, thedetail willcontain the following properties:host,ttl,result. The value ofresult issame as the result ofqueryxxx orgetHostByAddr.
Class:PerformanceNodeTiming#
- Extends:<PerformanceEntry>
This property is an extension by Node.js. It is not available in Web browsers.
Provides timing details for Node.js itself. The constructor of this classis not exposed to users.
performanceNodeTiming.bootstrapComplete#
- Type:<number>
The high resolution millisecond timestamp at which the Node.js processcompleted bootstrapping. If bootstrapping has not yet finished, the propertyhas the value of -1.
performanceNodeTiming.environment#
- Type:<number>
The high resolution millisecond timestamp at which the Node.js environment wasinitialized.
performanceNodeTiming.idleTime#
- Type:<number>
The high resolution millisecond timestamp of the amount of time the event loophas been idle within the event loop's event provider (e.g.epoll_wait). Thisdoes not take CPU usage into consideration. If the event loop has not yetstarted (e.g., in the first tick of the main script), the property has thevalue of 0.
performanceNodeTiming.loopExit#
- Type:<number>
The high resolution millisecond timestamp at which the Node.js event loopexited. If the event loop has not yet exited, the property has the value of -1.It can only have a value of not -1 in a handler of the'exit' event.
performanceNodeTiming.loopStart#
- Type:<number>
The high resolution millisecond timestamp at which the Node.js event loopstarted. If the event loop has not yet started (e.g., in the first tick of themain script), the property has the value of -1.
performanceNodeTiming.nodeStart#
- Type:<number>
The high resolution millisecond timestamp at which the Node.js process wasinitialized.
performanceNodeTiming.uvMetricsInfo#
- Returns:<Object>
This is a wrapper to theuv_metrics_info function.It returns the current set of event loop metrics.
It is recommended to use this property inside a function whose execution wasscheduled usingsetImmediate to avoid collecting metrics before finishing alloperations scheduled during the current loop iteration.
const { performance } =require('node:perf_hooks');setImmediate(() => {console.log(performance.nodeTiming.uvMetricsInfo);});import { performance }from'node:perf_hooks';setImmediate(() => {console.log(performance.nodeTiming.uvMetricsInfo);});
Class:PerformanceResourceTiming#
- Extends:<PerformanceEntry>
Provides detailed network timing data regarding the loading of an application'sresources.
The constructor of this class is not exposed to users directly.
performanceResourceTiming.workerStart#
History
| Version | Changes |
|---|---|
| v19.0.0 | This property getter must be called with the |
| v18.2.0, v16.17.0 | Added in: v18.2.0, v16.17.0 |
- Type:<number>
The high resolution millisecond timestamp at immediately before dispatchingthefetch request. If the resource is not intercepted by a worker the propertywill always return 0.
performanceResourceTiming.redirectStart#
History
| Version | Changes |
|---|---|
| v19.0.0 | This property getter must be called with the |
| v18.2.0, v16.17.0 | Added in: v18.2.0, v16.17.0 |
- Type:<number>
The high resolution millisecond timestamp that represents the start timeof the fetch which initiates the redirect.
performanceResourceTiming.redirectEnd#
History
| Version | Changes |
|---|---|
| v19.0.0 | This property getter must be called with the |
| v18.2.0, v16.17.0 | Added in: v18.2.0, v16.17.0 |
- Type:<number>
The high resolution millisecond timestamp that will be created immediately afterreceiving the last byte of the response of the last redirect.
performanceResourceTiming.fetchStart#
History
| Version | Changes |
|---|---|
| v19.0.0 | This property getter must be called with the |
| v18.2.0, v16.17.0 | Added in: v18.2.0, v16.17.0 |
- Type:<number>
The high resolution millisecond timestamp immediately before the Node.js startsto fetch the resource.
performanceResourceTiming.domainLookupStart#
History
| Version | Changes |
|---|---|
| v19.0.0 | This property getter must be called with the |
| v18.2.0, v16.17.0 | Added in: v18.2.0, v16.17.0 |
- Type:<number>
The high resolution millisecond timestamp immediately before the Node.js startsthe domain name lookup for the resource.
performanceResourceTiming.domainLookupEnd#
History
| Version | Changes |
|---|---|
| v19.0.0 | This property getter must be called with the |
| v18.2.0, v16.17.0 | Added in: v18.2.0, v16.17.0 |
- Type:<number>
The high resolution millisecond timestamp representing the time immediatelyafter the Node.js finished the domain name lookup for the resource.
performanceResourceTiming.connectStart#
History
| Version | Changes |
|---|---|
| v19.0.0 | This property getter must be called with the |
| v18.2.0, v16.17.0 | Added in: v18.2.0, v16.17.0 |
- Type:<number>
The high resolution millisecond timestamp representing the time immediatelybefore Node.js starts to establish the connection to the server to retrievethe resource.
performanceResourceTiming.connectEnd#
History
| Version | Changes |
|---|---|
| v19.0.0 | This property getter must be called with the |
| v18.2.0, v16.17.0 | Added in: v18.2.0, v16.17.0 |
- Type:<number>
The high resolution millisecond timestamp representing the time immediatelyafter Node.js finishes establishing the connection to the server to retrievethe resource.
performanceResourceTiming.secureConnectionStart#
History
| Version | Changes |
|---|---|
| v19.0.0 | This property getter must be called with the |
| v18.2.0, v16.17.0 | Added in: v18.2.0, v16.17.0 |
- Type:<number>
The high resolution millisecond timestamp representing the time immediatelybefore Node.js starts the handshake process to secure the current connection.
performanceResourceTiming.requestStart#
History
| Version | Changes |
|---|---|
| v19.0.0 | This property getter must be called with the |
| v18.2.0, v16.17.0 | Added in: v18.2.0, v16.17.0 |
- Type:<number>
The high resolution millisecond timestamp representing the time immediatelybefore Node.js receives the first byte of the response from the server.
performanceResourceTiming.responseEnd#
History
| Version | Changes |
|---|---|
| v19.0.0 | This property getter must be called with the |
| v18.2.0, v16.17.0 | Added in: v18.2.0, v16.17.0 |
- Type:<number>
The high resolution millisecond timestamp representing the time immediatelyafter Node.js receives the last byte of the resource or immediately beforethe transport connection is closed, whichever comes first.
performanceResourceTiming.transferSize#
History
| Version | Changes |
|---|---|
| v19.0.0 | This property getter must be called with the |
| v18.2.0, v16.17.0 | Added in: v18.2.0, v16.17.0 |
- Type:<number>
A number representing the size (in octets) of the fetched resource. The sizeincludes the response header fields plus the response payload body.
performanceResourceTiming.encodedBodySize#
History
| Version | Changes |
|---|---|
| v19.0.0 | This property getter must be called with the |
| v18.2.0, v16.17.0 | Added in: v18.2.0, v16.17.0 |
- Type:<number>
A number representing the size (in octets) received from the fetch(HTTP or cache), of the payload body, before removing any appliedcontent-codings.
performanceResourceTiming.decodedBodySize#
History
| Version | Changes |
|---|---|
| v19.0.0 | This property getter must be called with the |
| v18.2.0, v16.17.0 | Added in: v18.2.0, v16.17.0 |
- Type:<number>
A number representing the size (in octets) received from the fetch(HTTP or cache), of the message body, after removing any appliedcontent-codings.
performanceResourceTiming.toJSON()#
History
| Version | Changes |
|---|---|
| v19.0.0 | This method must be called with the |
| v18.2.0, v16.17.0 | Added in: v18.2.0, v16.17.0 |
Returns aobject that is the JSON representation of thePerformanceResourceTiming object
Class:PerformanceObserver#
new PerformanceObserver(callback)#
History
| Version | Changes |
|---|---|
| v18.0.0 | Passing an invalid callback to the |
| v8.5.0 | Added in: v8.5.0 |
callback<Function>
PerformanceObserver objects provide notifications when newPerformanceEntry instances have been added to the Performance Timeline.
import { performance,PerformanceObserver }from'node:perf_hooks';const obs =newPerformanceObserver((list, observer) => {console.log(list.getEntries()); performance.clearMarks(); performance.clearMeasures(); observer.disconnect();});obs.observe({entryTypes: ['mark'],buffered:true });performance.mark('test');const { performance,PerformanceObserver,} =require('node:perf_hooks');const obs =newPerformanceObserver((list, observer) => {console.log(list.getEntries()); performance.clearMarks(); performance.clearMeasures(); observer.disconnect();});obs.observe({entryTypes: ['mark'],buffered:true });performance.mark('test');
BecausePerformanceObserver instances introduce their own additionalperformance overhead, instances should not be left subscribed to notificationsindefinitely. Users should disconnect observers as soon as they are nolonger needed.
Thecallback is invoked when aPerformanceObserver isnotified about newPerformanceEntry instances. The callback receives aPerformanceObserverEntryList instance and a reference to thePerformanceObserver.
performanceObserver.disconnect()#
Disconnects thePerformanceObserver instance from all notifications.
performanceObserver.observe(options)#
History
| Version | Changes |
|---|---|
| v16.7.0 | Updated to conform to Performance Timeline Level 2. The buffered option has been added back. |
| v16.0.0 | Updated to conform to User Timing Level 3. The buffered option has been removed. |
| v8.5.0 | Added in: v8.5.0 |
options<Object>type<string> A single<PerformanceEntry> type. Must not be givenifentryTypesis already specified.entryTypes<string[]> An array of strings identifying the types of<PerformanceEntry> instances the observer is interested in. If notprovided an error will be thrown.buffered<boolean> If true, the observer callback is called with alist globalPerformanceEntrybuffered entries. If false, onlyPerformanceEntrys created after the time point are sent to theobserver callback.Default:false.
Subscribes the<PerformanceObserver> instance to notifications of new<PerformanceEntry> instances identified either byoptions.entryTypesoroptions.type:
import { performance,PerformanceObserver }from'node:perf_hooks';const obs =newPerformanceObserver((list, observer) => {// Called once asynchronously. `list` contains three items.});obs.observe({type:'mark' });for (let n =0; n <3; n++) performance.mark(`test${n}`);const { performance,PerformanceObserver,} =require('node:perf_hooks');const obs =newPerformanceObserver((list, observer) => {// Called once asynchronously. `list` contains three items.});obs.observe({type:'mark' });for (let n =0; n <3; n++) performance.mark(`test${n}`);
performanceObserver.takeRecords()#
- Returns:<PerformanceEntry[]> Current list of entries stored in the performance observer, emptying it out.
Class:PerformanceObserverEntryList#
ThePerformanceObserverEntryList class is used to provide access to thePerformanceEntry instances passed to aPerformanceObserver.The constructor of this class is not exposed to users.
performanceObserverEntryList.getEntries()#
- Returns:<PerformanceEntry[]>
Returns a list ofPerformanceEntry objects in chronological orderwith respect toperformanceEntry.startTime.
import { performance,PerformanceObserver }from'node:perf_hooks';const obs =newPerformanceObserver((perfObserverList, observer) => {console.log(perfObserverList.getEntries());/** * [ * PerformanceEntry { * name: 'test', * entryType: 'mark', * startTime: 81.465639, * duration: 0, * detail: null * }, * PerformanceEntry { * name: 'meow', * entryType: 'mark', * startTime: 81.860064, * duration: 0, * detail: null * } * ] */ performance.clearMarks(); performance.clearMeasures(); observer.disconnect();});obs.observe({type:'mark' });performance.mark('test');performance.mark('meow');const { performance,PerformanceObserver,} =require('node:perf_hooks');const obs =newPerformanceObserver((perfObserverList, observer) => {console.log(perfObserverList.getEntries());/** * [ * PerformanceEntry { * name: 'test', * entryType: 'mark', * startTime: 81.465639, * duration: 0, * detail: null * }, * PerformanceEntry { * name: 'meow', * entryType: 'mark', * startTime: 81.860064, * duration: 0, * detail: null * } * ] */ performance.clearMarks(); performance.clearMeasures(); observer.disconnect();});obs.observe({type:'mark' });performance.mark('test');performance.mark('meow');
performanceObserverEntryList.getEntriesByName(name[, type])#
name<string>type<string>- Returns:<PerformanceEntry[]>
Returns a list ofPerformanceEntry objects in chronological orderwith respect toperformanceEntry.startTime whoseperformanceEntry.name isequal toname, and optionally, whoseperformanceEntry.entryType is equal totype.
import { performance,PerformanceObserver }from'node:perf_hooks';const obs =newPerformanceObserver((perfObserverList, observer) => {console.log(perfObserverList.getEntriesByName('meow'));/** * [ * PerformanceEntry { * name: 'meow', * entryType: 'mark', * startTime: 98.545991, * duration: 0, * detail: null * } * ] */console.log(perfObserverList.getEntriesByName('nope'));// []console.log(perfObserverList.getEntriesByName('test','mark'));/** * [ * PerformanceEntry { * name: 'test', * entryType: 'mark', * startTime: 63.518931, * duration: 0, * detail: null * } * ] */console.log(perfObserverList.getEntriesByName('test','measure'));// [] performance.clearMarks(); performance.clearMeasures(); observer.disconnect();});obs.observe({entryTypes: ['mark','measure'] });performance.mark('test');performance.mark('meow');const { performance,PerformanceObserver,} =require('node:perf_hooks');const obs =newPerformanceObserver((perfObserverList, observer) => {console.log(perfObserverList.getEntriesByName('meow'));/** * [ * PerformanceEntry { * name: 'meow', * entryType: 'mark', * startTime: 98.545991, * duration: 0, * detail: null * } * ] */console.log(perfObserverList.getEntriesByName('nope'));// []console.log(perfObserverList.getEntriesByName('test','mark'));/** * [ * PerformanceEntry { * name: 'test', * entryType: 'mark', * startTime: 63.518931, * duration: 0, * detail: null * } * ] */console.log(perfObserverList.getEntriesByName('test','measure'));// [] performance.clearMarks(); performance.clearMeasures(); observer.disconnect();});obs.observe({entryTypes: ['mark','measure'] });performance.mark('test');performance.mark('meow');
performanceObserverEntryList.getEntriesByType(type)#
type<string>- Returns:<PerformanceEntry[]>
Returns a list ofPerformanceEntry objects in chronological orderwith respect toperformanceEntry.startTime whoseperformanceEntry.entryTypeis equal totype.
import { performance,PerformanceObserver }from'node:perf_hooks';const obs =newPerformanceObserver((perfObserverList, observer) => {console.log(perfObserverList.getEntriesByType('mark'));/** * [ * PerformanceEntry { * name: 'test', * entryType: 'mark', * startTime: 55.897834, * duration: 0, * detail: null * }, * PerformanceEntry { * name: 'meow', * entryType: 'mark', * startTime: 56.350146, * duration: 0, * detail: null * } * ] */ performance.clearMarks(); performance.clearMeasures(); observer.disconnect();});obs.observe({type:'mark' });performance.mark('test');performance.mark('meow');const { performance,PerformanceObserver,} =require('node:perf_hooks');const obs =newPerformanceObserver((perfObserverList, observer) => {console.log(perfObserverList.getEntriesByType('mark'));/** * [ * PerformanceEntry { * name: 'test', * entryType: 'mark', * startTime: 55.897834, * duration: 0, * detail: null * }, * PerformanceEntry { * name: 'meow', * entryType: 'mark', * startTime: 56.350146, * duration: 0, * detail: null * } * ] */ performance.clearMarks(); performance.clearMeasures(); observer.disconnect();});obs.observe({type:'mark' });performance.mark('test');performance.mark('meow');
perf_hooks.createHistogram([options])#
options<Object>lowest<number> |<bigint> The lowest discernible value. Must be an integervalue greater than 0.Default:1.highest<number> |<bigint> The highest recordable value. Must be an integervalue that is equal to or greater than two timeslowest.Default:Number.MAX_SAFE_INTEGER.figures<number> The number of accuracy digits. Must be a number between1and5.Default:3.
- Returns:<RecordableHistogram>
Returns a<RecordableHistogram>.
perf_hooks.monitorEventLoopDelay([options])#
options<Object>resolution<number> The sampling rate in milliseconds. Must be greaterthan zero.Default:10.
- Returns:<IntervalHistogram>
This property is an extension by Node.js. It is not available in Web browsers.
Creates anIntervalHistogram object that samples and reports the event loopdelay over time. The delays will be reported in nanoseconds.
Using a timer to detect approximate event loop delay works because theexecution of timers is tied specifically to the lifecycle of the libuvevent loop. That is, a delay in the loop will cause a delay in the executionof the timer, and those delays are specifically what this API is intended todetect.
import { monitorEventLoopDelay }from'node:perf_hooks';const h =monitorEventLoopDelay({resolution:20 });h.enable();// Do something.h.disable();console.log(h.min);console.log(h.max);console.log(h.mean);console.log(h.stddev);console.log(h.percentiles);console.log(h.percentile(50));console.log(h.percentile(99));const { monitorEventLoopDelay } =require('node:perf_hooks');const h =monitorEventLoopDelay({resolution:20 });h.enable();// Do something.h.disable();console.log(h.min);console.log(h.max);console.log(h.mean);console.log(h.stddev);console.log(h.percentiles);console.log(h.percentile(50));console.log(h.percentile(99));
Class:Histogram#
histogram.count#
- Type:<number>
The number of samples recorded by the histogram.
histogram.countBigInt#
- Type:<bigint>
The number of samples recorded by the histogram.
histogram.exceeds#
- Type:<number>
The number of times the event loop delay exceeded the maximum 1 hour eventloop delay threshold.
histogram.exceedsBigInt#
- Type:<bigint>
The number of times the event loop delay exceeded the maximum 1 hour eventloop delay threshold.
histogram.percentileBigInt(percentile)#
Returns the value at the given percentile.
histogram.percentiles#
- Type:<Map>
Returns aMap object detailing the accumulated percentile distribution.
Class:IntervalHistogram extends Histogram#
AHistogram that is periodically updated on a given interval.
histogram.disable()#
- Returns:<boolean>
Disables the update interval timer. Returnstrue if the timer wasstopped,false if it was already stopped.
histogram.enable()#
- Returns:<boolean>
Enables the update interval timer. Returnstrue if the timer wasstarted,false if it was already started.
histogram[Symbol.dispose]()#
Disables the update interval timer when the histogram is disposed.
const { monitorEventLoopDelay } =require('node:perf_hooks');{using hist =monitorEventLoopDelay({resolution:20 }); hist.enable();// The histogram will be disabled when the block is exited.}Cloning anIntervalHistogram#
<IntervalHistogram> instances can be cloned via<MessagePort>. On the receivingend, the histogram is cloned as a plain<Histogram> object that does notimplement theenable() anddisable() methods.
Class:RecordableHistogram extends Histogram#
histogram.record(val)#
histogram.recordDelta()#
Calculates the amount of time (in nanoseconds) that has passed since theprevious call torecordDelta() and records that amount in the histogram.
Examples#
Measuring the duration of async operations#
The following example uses theAsync Hooks and Performance APIs to measurethe actual duration of a Timeout operation (including the amount of time it tookto execute the callback).
import { createHook }from'node:async_hooks';import { performance,PerformanceObserver }from'node:perf_hooks';const set =newSet();const hook =createHook({init(id, type) {if (type ==='Timeout') { performance.mark(`Timeout-${id}-Init`); set.add(id); } },destroy(id) {if (set.has(id)) { set.delete(id); performance.mark(`Timeout-${id}-Destroy`); performance.measure(`Timeout-${id}`,`Timeout-${id}-Init`,`Timeout-${id}-Destroy`); } },});hook.enable();const obs =newPerformanceObserver((list, observer) => {console.log(list.getEntries()[0]); performance.clearMarks(); performance.clearMeasures(); observer.disconnect();});obs.observe({entryTypes: ['measure'],buffered:true });setTimeout(() => {},1000);'use strict';const async_hooks =require('node:async_hooks');const { performance,PerformanceObserver,} =require('node:perf_hooks');const set =newSet();const hook = async_hooks.createHook({init(id, type) {if (type ==='Timeout') { performance.mark(`Timeout-${id}-Init`); set.add(id); } },destroy(id) {if (set.has(id)) { set.delete(id); performance.mark(`Timeout-${id}-Destroy`); performance.measure(`Timeout-${id}`,`Timeout-${id}-Init`,`Timeout-${id}-Destroy`); } },});hook.enable();const obs =newPerformanceObserver((list, observer) => {console.log(list.getEntries()[0]); performance.clearMarks(); performance.clearMeasures(); observer.disconnect();});obs.observe({entryTypes: ['measure'] });setTimeout(() => {},1000);
Measuring how long it takes to load dependencies#
The following example measures the duration ofrequire() operations to loaddependencies:
import { performance,PerformanceObserver }from'node:perf_hooks';// Activate the observerconst obs =newPerformanceObserver((list) => {const entries = list.getEntries(); entries.forEach((entry) => {console.log(`import('${entry[0]}')`, entry.duration); }); performance.clearMarks(); performance.clearMeasures(); obs.disconnect();});obs.observe({entryTypes: ['function'],buffered:true });const timedImport = performance.timerify(async (module) => {returnawaitimport(module);});awaittimedImport('some-module');'use strict';const { performance,PerformanceObserver,} =require('node:perf_hooks');const mod =require('node:module');// Monkey patch the require functionmod.Module.prototype.require = performance.timerify(mod.Module.prototype.require);require = performance.timerify(require);// Activate the observerconst obs =newPerformanceObserver((list) => {const entries = list.getEntries(); entries.forEach((entry) => {console.log(`require('${entry[0]}')`, entry.duration); }); performance.clearMarks(); performance.clearMeasures(); obs.disconnect();});obs.observe({entryTypes: ['function'] });require('some-module');
Measuring how long one HTTP round-trip takes#
The following example is used to trace the time spent by HTTP client(OutgoingMessage) and HTTP request (IncomingMessage). For HTTP client,it means the time interval between starting the request and receiving theresponse, and for HTTP request, it means the time interval between receivingthe request and sending the response:
import {PerformanceObserver }from'node:perf_hooks';import { createServer, get }from'node:http';const obs =newPerformanceObserver((items) => { items.getEntries().forEach((item) => {console.log(item); });});obs.observe({entryTypes: ['http'] });constPORT =8080;createServer((req, res) => { res.end('ok');}).listen(PORT,() => {get(`http://127.0.0.1:${PORT}`);});'use strict';const {PerformanceObserver } =require('node:perf_hooks');const http =require('node:http');const obs =newPerformanceObserver((items) => { items.getEntries().forEach((item) => {console.log(item); });});obs.observe({entryTypes: ['http'] });constPORT =8080;http.createServer((req, res) => { res.end('ok');}).listen(PORT,() => { http.get(`http://127.0.0.1:${PORT}`);});
Measuring how long thenet.connect (only for TCP) takes when the connection is successful#
import {PerformanceObserver }from'node:perf_hooks';import { connect, createServer }from'node:net';const obs =newPerformanceObserver((items) => { items.getEntries().forEach((item) => {console.log(item); });});obs.observe({entryTypes: ['net'] });constPORT =8080;createServer((socket) => { socket.destroy();}).listen(PORT,() => {connect(PORT);});'use strict';const {PerformanceObserver } =require('node:perf_hooks');const net =require('node:net');const obs =newPerformanceObserver((items) => { items.getEntries().forEach((item) => {console.log(item); });});obs.observe({entryTypes: ['net'] });constPORT =8080;net.createServer((socket) => { socket.destroy();}).listen(PORT,() => { net.connect(PORT);});
Measuring how long the DNS takes when the request is successful#
import {PerformanceObserver }from'node:perf_hooks';import { lookup, promises }from'node:dns';const obs =newPerformanceObserver((items) => { items.getEntries().forEach((item) => {console.log(item); });});obs.observe({entryTypes: ['dns'] });lookup('localhost',() => {});promises.resolve('localhost');'use strict';const {PerformanceObserver } =require('node:perf_hooks');const dns =require('node:dns');const obs =newPerformanceObserver((items) => { items.getEntries().forEach((item) => {console.log(item); });});obs.observe({entryTypes: ['dns'] });dns.lookup('localhost',() => {});dns.promises.resolve('localhost');