1# Performance measurement APIs 2 3<!--introduced_in=v8.5.0--> 4 5> Stability: 2 - Stable 6 7<!-- source_link=lib/perf_hooks.js --> 8 9This module provides an implementation of a subset of the W3C 10[Web Performance APIs][] as well as additional APIs for 11Node.js-specific performance measurements. 12 13Node.js supports the following [Web Performance APIs][]: 14 15* [High Resolution Time][] 16* [Performance Timeline][] 17* [User Timing][] 18* [Resource Timing][] 19 20```js 21const { PerformanceObserver, performance } = require('node:perf_hooks'); 22 23const obs = new PerformanceObserver((items) => { 24 console.log(items.getEntries()[0].duration); 25 performance.clearMarks(); 26}); 27obs.observe({ type: 'measure' }); 28performance.measure('Start to Now'); 29 30performance.mark('A'); 31doSomeLongRunningProcess(() => { 32 performance.measure('A to Now', 'A'); 33 34 performance.mark('B'); 35 performance.measure('A to B', 'A', 'B'); 36}); 37``` 38 39## `perf_hooks.performance` 40 41<!-- YAML 42added: v8.5.0 43--> 44 45An object that can be used to collect performance metrics from the current 46Node.js instance. It is similar to [`window.performance`][] in browsers. 47 48### `performance.clearMarks([name])` 49 50<!-- YAML 51added: v8.5.0 52--> 53 54* `name` {string} 55 56If `name` is not provided, removes all `PerformanceMark` objects from the 57Performance Timeline. If `name` is provided, removes only the named mark. 58 59### `performance.clearMeasures([name])` 60 61<!-- YAML 62added: v16.7.0 63--> 64 65* `name` {string} 66 67If `name` is not provided, removes all `PerformanceMeasure` objects from the 68Performance Timeline. If `name` is provided, removes only the named measure. 69 70### `performance.clearResourceTimings([name])` 71 72<!-- YAML 73added: v18.2.0 74--> 75 76* `name` {string} 77 78If `name` is not provided, removes all `PerformanceResourceTiming` objects from 79the Resource Timeline. If `name` is provided, removes only the named resource. 80 81### `performance.eventLoopUtilization([utilization1[, utilization2]])` 82 83<!-- YAML 84added: 85 - v14.10.0 86 - v12.19.0 87--> 88 89* `utilization1` {Object} The result of a previous call to 90 `eventLoopUtilization()`. 91* `utilization2` {Object} The result of a previous call to 92 `eventLoopUtilization()` prior to `utilization1`. 93* Returns {Object} 94 * `idle` {number} 95 * `active` {number} 96 * `utilization` {number} 97 98The `eventLoopUtilization()` method returns an object that contains the 99cumulative duration of time the event loop has been both idle and active as a 100high resolution milliseconds timer. The `utilization` value is the calculated 101Event Loop Utilization (ELU). 102 103If bootstrapping has not yet finished on the main thread the properties have 104the value of `0`. The ELU is immediately available on [Worker threads][] since 105bootstrap happens within the event loop. 106 107Both `utilization1` and `utilization2` are optional parameters. 108 109If `utilization1` is passed, then the delta between the current call's `active` 110and `idle` times, as well as the corresponding `utilization` value are 111calculated and returned (similar to [`process.hrtime()`][]). 112 113If `utilization1` and `utilization2` are both passed, then the delta is 114calculated between the two arguments. This is a convenience option because, 115unlike [`process.hrtime()`][], calculating the ELU is more complex than a 116single subtraction. 117 118ELU is similar to CPU utilization, except that it only measures event loop 119statistics and not CPU usage. It represents the percentage of time the event 120loop has spent outside the event loop's event provider (e.g. `epoll_wait`). 121No other CPU idle time is taken into consideration. The following is an example 122of how a mostly idle process will have a high ELU. 123 124```js 125'use strict'; 126const { eventLoopUtilization } = require('node:perf_hooks').performance; 127const { spawnSync } = require('node:child_process'); 128 129setImmediate(() => { 130 const elu = eventLoopUtilization(); 131 spawnSync('sleep', ['5']); 132 console.log(eventLoopUtilization(elu).utilization); 133}); 134``` 135 136Although the CPU is mostly idle while running this script, the value of 137`utilization` is `1`. This is because the call to 138[`child_process.spawnSync()`][] blocks the event loop from proceeding. 139 140Passing in a user-defined object instead of the result of a previous call to 141`eventLoopUtilization()` will lead to undefined behavior. The return values 142are not guaranteed to reflect any correct state of the event loop. 143 144### `performance.getEntries()` 145 146<!-- YAML 147added: v16.7.0 148--> 149 150* Returns: {PerformanceEntry\[]} 151 152Returns a list of `PerformanceEntry` objects in chronological order with 153respect to `performanceEntry.startTime`. If you are only interested in 154performance entries of certain types or that have certain names, see 155`performance.getEntriesByType()` and `performance.getEntriesByName()`. 156 157### `performance.getEntriesByName(name[, type])` 158 159<!-- YAML 160added: v16.7.0 161--> 162 163* `name` {string} 164* `type` {string} 165* Returns: {PerformanceEntry\[]} 166 167Returns a list of `PerformanceEntry` objects in chronological order 168with respect to `performanceEntry.startTime` whose `performanceEntry.name` is 169equal to `name`, and optionally, whose `performanceEntry.entryType` is equal to 170`type`. 171 172### `performance.getEntriesByType(type)` 173 174<!-- YAML 175added: v16.7.0 176--> 177 178* `type` {string} 179* Returns: {PerformanceEntry\[]} 180 181Returns a list of `PerformanceEntry` objects in chronological order 182with respect to `performanceEntry.startTime` whose `performanceEntry.entryType` 183is equal to `type`. 184 185### `performance.mark([name[, options]])` 186 187<!-- YAML 188added: v8.5.0 189changes: 190 - version: v16.0.0 191 pr-url: https://github.com/nodejs/node/pull/37136 192 description: Updated to conform to the User Timing Level 3 specification. 193--> 194 195* `name` {string} 196* `options` {Object} 197 * `detail` {any} Additional optional detail to include with the mark. 198 * `startTime` {number} An optional timestamp to be used as the mark time. 199 **Default**: `performance.now()`. 200 201Creates a new `PerformanceMark` entry in the Performance Timeline. A 202`PerformanceMark` is a subclass of `PerformanceEntry` whose 203`performanceEntry.entryType` is always `'mark'`, and whose 204`performanceEntry.duration` is always `0`. Performance marks are used 205to mark specific significant moments in the Performance Timeline. 206 207The created `PerformanceMark` entry is put in the global Performance Timeline 208and can be queried with `performance.getEntries`, 209`performance.getEntriesByName`, and `performance.getEntriesByType`. When the 210observation is performed, the entries should be cleared from the global 211Performance Timeline manually with `performance.clearMarks`. 212 213### `performance.markResourceTiming(timingInfo, requestedUrl, initiatorType, global, cacheMode)` 214 215<!-- YAML 216added: v18.2.0 217--> 218 219* `timingInfo` {Object} [Fetch Timing Info][] 220* `requestedUrl` {string} The resource url 221* `initiatorType` {string} The initiator name, e.g: 'fetch' 222* `global` {Object} 223* `cacheMode` {string} The cache mode must be an empty string ('') or 'local' 224 225_This property is an extension by Node.js. It is not available in Web browsers._ 226 227Creates a new `PerformanceResourceTiming` entry in the Resource Timeline. A 228`PerformanceResourceTiming` is a subclass of `PerformanceEntry` whose 229`performanceEntry.entryType` is always `'resource'`. Performance resources 230are used to mark moments in the Resource Timeline. 231 232The created `PerformanceMark` entry is put in the global Resource Timeline 233and can be queried with `performance.getEntries`, 234`performance.getEntriesByName`, and `performance.getEntriesByType`. When the 235observation is performed, the entries should be cleared from the global 236Performance Timeline manually with `performance.clearResourceTimings`. 237 238### `performance.measure(name[, startMarkOrOptions[, endMark]])` 239 240<!-- YAML 241added: v8.5.0 242changes: 243 - version: v16.0.0 244 pr-url: https://github.com/nodejs/node/pull/37136 245 description: Updated to conform to the User Timing Level 3 specification. 246 - version: 247 - v13.13.0 248 - v12.16.3 249 pr-url: https://github.com/nodejs/node/pull/32651 250 description: Make `startMark` and `endMark` parameters optional. 251--> 252 253* `name` {string} 254* `startMarkOrOptions` {string|Object} Optional. 255 * `detail` {any} Additional optional detail to include with the measure. 256 * `duration` {number} Duration between start and end times. 257 * `end` {number|string} Timestamp to be used as the end time, or a string 258 identifying a previously recorded mark. 259 * `start` {number|string} Timestamp to be used as the start time, or a string 260 identifying a previously recorded mark. 261* `endMark` {string} Optional. Must be omitted if `startMarkOrOptions` is an 262 {Object}. 263 264Creates a new `PerformanceMeasure` entry in the Performance Timeline. A 265`PerformanceMeasure` is a subclass of `PerformanceEntry` whose 266`performanceEntry.entryType` is always `'measure'`, and whose 267`performanceEntry.duration` measures the number of milliseconds elapsed since 268`startMark` and `endMark`. 269 270The `startMark` argument may identify any _existing_ `PerformanceMark` in the 271Performance Timeline, or _may_ identify any of the timestamp properties 272provided by the `PerformanceNodeTiming` class. If the named `startMark` does 273not exist, an error is thrown. 274 275The optional `endMark` argument must identify any _existing_ `PerformanceMark` 276in the Performance Timeline or any of the timestamp properties provided by the 277`PerformanceNodeTiming` class. `endMark` will be `performance.now()` 278if no parameter is passed, otherwise if the named `endMark` does not exist, an 279error will be thrown. 280 281The created `PerformanceMeasure` entry is put in the global Performance Timeline 282and can be queried with `performance.getEntries`, 283`performance.getEntriesByName`, and `performance.getEntriesByType`. When the 284observation is performed, the entries should be cleared from the global 285Performance Timeline manually with `performance.clearMeasures`. 286 287### `performance.nodeTiming` 288 289<!-- YAML 290added: v8.5.0 291--> 292 293* {PerformanceNodeTiming} 294 295_This property is an extension by Node.js. It is not available in Web browsers._ 296 297An instance of the `PerformanceNodeTiming` class that provides performance 298metrics for specific Node.js operational milestones. 299 300### `performance.now()` 301 302<!-- YAML 303added: v8.5.0 304--> 305 306* Returns: {number} 307 308Returns the current high resolution millisecond timestamp, where 0 represents 309the start of the current `node` process. 310 311### `performance.setResourceTimingBufferSize(maxSize)` 312 313<!-- YAML 314added: v18.8.0 315--> 316 317Sets the global performance resource timing buffer size to the specified number 318of "resource" type performance entry objects. 319 320By default the max buffer size is set to 250. 321 322### `performance.timeOrigin` 323 324<!-- YAML 325added: v8.5.0 326--> 327 328* {number} 329 330The [`timeOrigin`][] specifies the high resolution millisecond timestamp at 331which the current `node` process began, measured in Unix time. 332 333### `performance.timerify(fn[, options])` 334 335<!-- YAML 336added: v8.5.0 337changes: 338 - version: v16.0.0 339 pr-url: https://github.com/nodejs/node/pull/37475 340 description: Added the histogram option. 341 - version: v16.0.0 342 pr-url: https://github.com/nodejs/node/pull/37136 343 description: Re-implemented to use pure-JavaScript and the ability 344 to time async functions. 345--> 346 347* `fn` {Function} 348* `options` {Object} 349 * `histogram` {RecordableHistogram} A histogram object created using 350 `perf_hooks.createHistogram()` that will record runtime durations in 351 nanoseconds. 352 353_This property is an extension by Node.js. It is not available in Web browsers._ 354 355Wraps a function within a new function that measures the running time of the 356wrapped function. A `PerformanceObserver` must be subscribed to the `'function'` 357event type in order for the timing details to be accessed. 358 359```js 360const { 361 performance, 362 PerformanceObserver, 363} = require('node:perf_hooks'); 364 365function someFunction() { 366 console.log('hello world'); 367} 368 369const wrapped = performance.timerify(someFunction); 370 371const obs = new PerformanceObserver((list) => { 372 console.log(list.getEntries()[0].duration); 373 374 performance.clearMarks(); 375 performance.clearMeasures(); 376 obs.disconnect(); 377}); 378obs.observe({ entryTypes: ['function'] }); 379 380// A performance timeline entry will be created 381wrapped(); 382``` 383 384If the wrapped function returns a promise, a finally handler will be attached 385to the promise and the duration will be reported once the finally handler is 386invoked. 387 388### `performance.toJSON()` 389 390<!-- YAML 391added: v16.1.0 392--> 393 394An object which is JSON representation of the `performance` object. It 395is similar to [`window.performance.toJSON`][] in browsers. 396 397#### Event: `'resourcetimingbufferfull'` 398 399<!-- YAML 400added: v18.8.0 401--> 402 403The `'resourcetimingbufferfull'` event is fired when the global performance 404resource timing buffer is full. Adjust resource timing buffer size with 405`performance.setResourceTimingBufferSize()` or clear the buffer with 406`performance.clearResourceTimings()` in the event listener to allow 407more entries to be added to the performance timeline buffer. 408 409## Class: `PerformanceEntry` 410 411<!-- YAML 412added: v8.5.0 413--> 414 415### `performanceEntry.detail` 416 417<!-- YAML 418added: v16.0.0 419--> 420 421* {any} 422 423Additional detail specific to the `entryType`. 424 425### `performanceEntry.duration` 426 427<!-- YAML 428added: v8.5.0 429--> 430 431* {number} 432 433The total number of milliseconds elapsed for this entry. This value will not 434be meaningful for all Performance Entry types. 435 436### `performanceEntry.entryType` 437 438<!-- YAML 439added: v8.5.0 440--> 441 442* {string} 443 444The type of the performance entry. It may be one of: 445 446* `'node'` (Node.js only) 447* `'mark'` (available on the Web) 448* `'measure'` (available on the Web) 449* `'gc'` (Node.js only) 450* `'function'` (Node.js only) 451* `'http2'` (Node.js only) 452* `'http'` (Node.js only) 453 454### `performanceEntry.flags` 455 456<!-- YAML 457added: 458 - v13.9.0 459 - v12.17.0 460changes: 461 - version: v16.0.0 462 pr-url: https://github.com/nodejs/node/pull/37136 463 description: Runtime deprecated. Now moved to the detail property 464 when entryType is 'gc'. 465--> 466 467* {number} 468 469_This property is an extension by Node.js. It is not available in Web browsers._ 470 471When `performanceEntry.entryType` is equal to `'gc'`, the `performance.flags` 472property contains additional information about garbage collection operation. 473The value may be one of: 474 475* `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_NO` 476* `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_CONSTRUCT_RETAINED` 477* `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_FORCED` 478* `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_SYNCHRONOUS_PHANTOM_PROCESSING` 479* `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_ALL_AVAILABLE_GARBAGE` 480* `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_ALL_EXTERNAL_MEMORY` 481* `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_SCHEDULE_IDLE` 482 483### `performanceEntry.name` 484 485<!-- YAML 486added: v8.5.0 487--> 488 489* {string} 490 491The name of the performance entry. 492 493### `performanceEntry.kind` 494 495<!-- YAML 496added: v8.5.0 497changes: 498 - version: v16.0.0 499 pr-url: https://github.com/nodejs/node/pull/37136 500 description: Runtime deprecated. Now moved to the detail property 501 when entryType is 'gc'. 502--> 503 504* {number} 505 506_This property is an extension by Node.js. It is not available in Web browsers._ 507 508When `performanceEntry.entryType` is equal to `'gc'`, the `performance.kind` 509property identifies the type of garbage collection operation that occurred. 510The value may be one of: 511 512* `perf_hooks.constants.NODE_PERFORMANCE_GC_MAJOR` 513* `perf_hooks.constants.NODE_PERFORMANCE_GC_MINOR` 514* `perf_hooks.constants.NODE_PERFORMANCE_GC_INCREMENTAL` 515* `perf_hooks.constants.NODE_PERFORMANCE_GC_WEAKCB` 516 517### `performanceEntry.startTime` 518 519<!-- YAML 520added: v8.5.0 521--> 522 523* {number} 524 525The high resolution millisecond timestamp marking the starting time of the 526Performance Entry. 527 528### Garbage Collection ('gc') Details 529 530When `performanceEntry.type` is equal to `'gc'`, the `performanceEntry.detail` 531property will be an {Object} with two properties: 532 533* `kind` {number} One of: 534 * `perf_hooks.constants.NODE_PERFORMANCE_GC_MAJOR` 535 * `perf_hooks.constants.NODE_PERFORMANCE_GC_MINOR` 536 * `perf_hooks.constants.NODE_PERFORMANCE_GC_INCREMENTAL` 537 * `perf_hooks.constants.NODE_PERFORMANCE_GC_WEAKCB` 538* `flags` {number} One of: 539 * `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_NO` 540 * `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_CONSTRUCT_RETAINED` 541 * `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_FORCED` 542 * `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_SYNCHRONOUS_PHANTOM_PROCESSING` 543 * `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_ALL_AVAILABLE_GARBAGE` 544 * `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_ALL_EXTERNAL_MEMORY` 545 * `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_SCHEDULE_IDLE` 546 547### HTTP ('http') Details 548 549When `performanceEntry.type` is equal to `'http'`, the `performanceEntry.detail` 550property will be an {Object} containing additional information. 551 552If `performanceEntry.name` is equal to `HttpClient`, the `detail` 553will contain the following properties: `req`, `res`. And the `req` property 554will be an {Object} containing `method`, `url`, `headers`, the `res` property 555will be an {Object} containing `statusCode`, `statusMessage`, `headers`. 556 557If `performanceEntry.name` is equal to `HttpRequest`, the `detail` 558will contain the following properties: `req`, `res`. And the `req` property 559will be an {Object} containing `method`, `url`, `headers`, the `res` property 560will be an {Object} containing `statusCode`, `statusMessage`, `headers`. 561 562This could add additional memory overhead and should only be used for 563diagnostic purposes, not left turned on in production by default. 564 565### HTTP/2 ('http2') Details 566 567When `performanceEntry.type` is equal to `'http2'`, the 568`performanceEntry.detail` property will be an {Object} containing 569additional performance information. 570 571If `performanceEntry.name` is equal to `Http2Stream`, the `detail` 572will contain the following properties: 573 574* `bytesRead` {number} The number of `DATA` frame bytes received for this 575 `Http2Stream`. 576* `bytesWritten` {number} The number of `DATA` frame bytes sent for this 577 `Http2Stream`. 578* `id` {number} The identifier of the associated `Http2Stream` 579* `timeToFirstByte` {number} The number of milliseconds elapsed between the 580 `PerformanceEntry` `startTime` and the reception of the first `DATA` frame. 581* `timeToFirstByteSent` {number} The number of milliseconds elapsed between 582 the `PerformanceEntry` `startTime` and sending of the first `DATA` frame. 583* `timeToFirstHeader` {number} The number of milliseconds elapsed between the 584 `PerformanceEntry` `startTime` and the reception of the first header. 585 586If `performanceEntry.name` is equal to `Http2Session`, the `detail` will 587contain the following properties: 588 589* `bytesRead` {number} The number of bytes received for this `Http2Session`. 590* `bytesWritten` {number} The number of bytes sent for this `Http2Session`. 591* `framesReceived` {number} The number of HTTP/2 frames received by the 592 `Http2Session`. 593* `framesSent` {number} The number of HTTP/2 frames sent by the `Http2Session`. 594* `maxConcurrentStreams` {number} The maximum number of streams concurrently 595 open during the lifetime of the `Http2Session`. 596* `pingRTT` {number} The number of milliseconds elapsed since the transmission 597 of a `PING` frame and the reception of its acknowledgment. Only present if 598 a `PING` frame has been sent on the `Http2Session`. 599* `streamAverageDuration` {number} The average duration (in milliseconds) for 600 all `Http2Stream` instances. 601* `streamCount` {number} The number of `Http2Stream` instances processed by 602 the `Http2Session`. 603* `type` {string} Either `'server'` or `'client'` to identify the type of 604 `Http2Session`. 605 606### Timerify ('function') Details 607 608When `performanceEntry.type` is equal to `'function'`, the 609`performanceEntry.detail` property will be an {Array} listing 610the input arguments to the timed function. 611 612### Net ('net') Details 613 614When `performanceEntry.type` is equal to `'net'`, the 615`performanceEntry.detail` property will be an {Object} containing 616additional information. 617 618If `performanceEntry.name` is equal to `connect`, the `detail` 619will contain the following properties: `host`, `port`. 620 621### DNS ('dns') Details 622 623When `performanceEntry.type` is equal to `'dns'`, the 624`performanceEntry.detail` property will be an {Object} containing 625additional information. 626 627If `performanceEntry.name` is equal to `lookup`, the `detail` 628will contain the following properties: `hostname`, `family`, `hints`, `verbatim`, 629`addresses`. 630 631If `performanceEntry.name` is equal to `lookupService`, the `detail` will 632contain the following properties: `host`, `port`, `hostname`, `service`. 633 634If `performanceEntry.name` is equal to `queryxxx` or `getHostByAddr`, the `detail` will 635contain the following properties: `host`, `ttl`, `result`. The value of `result` is 636same as the result of `queryxxx` or `getHostByAddr`. 637 638## Class: `PerformanceNodeTiming` 639 640<!-- YAML 641added: v8.5.0 642--> 643 644* Extends: {PerformanceEntry} 645 646_This property is an extension by Node.js. It is not available in Web browsers._ 647 648Provides timing details for Node.js itself. The constructor of this class 649is not exposed to users. 650 651### `performanceNodeTiming.bootstrapComplete` 652 653<!-- YAML 654added: v8.5.0 655--> 656 657* {number} 658 659The high resolution millisecond timestamp at which the Node.js process 660completed bootstrapping. If bootstrapping has not yet finished, the property 661has the value of -1. 662 663### `performanceNodeTiming.environment` 664 665<!-- YAML 666added: v8.5.0 667--> 668 669* {number} 670 671The high resolution millisecond timestamp at which the Node.js environment was 672initialized. 673 674### `performanceNodeTiming.idleTime` 675 676<!-- YAML 677added: 678 - v14.10.0 679 - v12.19.0 680--> 681 682* {number} 683 684The high resolution millisecond timestamp of the amount of time the event loop 685has been idle within the event loop's event provider (e.g. `epoll_wait`). This 686does not take CPU usage into consideration. If the event loop has not yet 687started (e.g., in the first tick of the main script), the property has the 688value of 0. 689 690### `performanceNodeTiming.loopExit` 691 692<!-- YAML 693added: v8.5.0 694--> 695 696* {number} 697 698The high resolution millisecond timestamp at which the Node.js event loop 699exited. If the event loop has not yet exited, the property has the value of -1. 700It can only have a value of not -1 in a handler of the [`'exit'`][] event. 701 702### `performanceNodeTiming.loopStart` 703 704<!-- YAML 705added: v8.5.0 706--> 707 708* {number} 709 710The high resolution millisecond timestamp at which the Node.js event loop 711started. If the event loop has not yet started (e.g., in the first tick of the 712main script), the property has the value of -1. 713 714### `performanceNodeTiming.nodeStart` 715 716<!-- YAML 717added: v8.5.0 718--> 719 720* {number} 721 722The high resolution millisecond timestamp at which the Node.js process was 723initialized. 724 725### `performanceNodeTiming.v8Start` 726 727<!-- YAML 728added: v8.5.0 729--> 730 731* {number} 732 733The high resolution millisecond timestamp at which the V8 platform was 734initialized. 735 736## Class: `PerformanceResourceTiming` 737 738<!-- YAML 739added: v18.2.0 740--> 741 742* Extends: {PerformanceEntry} 743 744Provides detailed network timing data regarding the loading of an application's 745resources. 746 747The constructor of this class is not exposed to users directly. 748 749### `performanceResourceTiming.workerStart` 750 751<!-- YAML 752added: v18.2.0 753--> 754 755* {number} 756 757The high resolution millisecond timestamp at immediately before dispatching 758the `fetch` request. If the resource is not intercepted by a worker the property 759will always return 0. 760 761### `performanceResourceTiming.redirectStart` 762 763<!-- YAML 764added: v18.2.0 765--> 766 767* {number} 768 769The high resolution millisecond timestamp that represents the start time 770of the fetch which initiates the redirect. 771 772### `performanceResourceTiming.redirectEnd` 773 774<!-- YAML 775added: v18.2.0 776--> 777 778* {number} 779 780The high resolution millisecond timestamp that will be created immediately after 781receiving the last byte of the response of the last redirect. 782 783### `performanceResourceTiming.fetchStart` 784 785<!-- YAML 786added: v18.2.0 787--> 788 789* {number} 790 791The high resolution millisecond timestamp immediately before the Node.js starts 792to fetch the resource. 793 794### `performanceResourceTiming.domainLookupStart` 795 796<!-- YAML 797added: v18.2.0 798--> 799 800* {number} 801 802The high resolution millisecond timestamp immediately before the Node.js starts 803the domain name lookup for the resource. 804 805### `performanceResourceTiming.domainLookupEnd` 806 807<!-- YAML 808added: v18.2.0 809--> 810 811* {number} 812 813The high resolution millisecond timestamp representing the time immediately 814after the Node.js finished the domain name lookup for the resource. 815 816### `performanceResourceTiming.connectStart` 817 818<!-- YAML 819added: v18.2.0 820--> 821 822* {number} 823 824The high resolution millisecond timestamp representing the time immediately 825before Node.js starts to establish the connection to the server to retrieve 826the resource. 827 828### `performanceResourceTiming.connectEnd` 829 830<!-- YAML 831added: v18.2.0 832--> 833 834* {number} 835 836The high resolution millisecond timestamp representing the time immediately 837after Node.js finishes establishing the connection to the server to retrieve 838the resource. 839 840### `performanceResourceTiming.secureConnectionStart` 841 842<!-- YAML 843added: v18.2.0 844--> 845 846* {number} 847 848The high resolution millisecond timestamp representing the time immediately 849before Node.js starts the handshake process to secure the current connection. 850 851### `performanceResourceTiming.requestStart` 852 853<!-- YAML 854added: v18.2.0 855--> 856 857* {number} 858 859The high resolution millisecond timestamp representing the time immediately 860before Node.js receives the first byte of the response from the server. 861 862### `performanceResourceTiming.responseEnd` 863 864<!-- YAML 865added: v18.2.0 866--> 867 868* {number} 869 870The high resolution millisecond timestamp representing the time immediately 871after Node.js receives the last byte of the resource or immediately before 872the transport connection is closed, whichever comes first. 873 874### `performanceResourceTiming.transferSize` 875 876<!-- YAML 877added: v18.2.0 878--> 879 880* {number} 881 882A number representing the size (in octets) of the fetched resource. The size 883includes the response header fields plus the response payload body. 884 885### `performanceResourceTiming.encodedBodySize` 886 887<!-- YAML 888added: v18.2.0 889--> 890 891* {number} 892 893A number representing the size (in octets) received from the fetch 894(HTTP or cache), of the payload body, before removing any applied 895content-codings. 896 897### `performanceResourceTiming.decodedBodySize` 898 899<!-- YAML 900added: v18.2.0 901--> 902 903* {number} 904 905A number representing the size (in octets) received from the fetch 906(HTTP or cache), of the message body, after removing any applied 907content-codings. 908 909### `performanceResourceTiming.toJSON()` 910 911<!-- YAML 912added: v18.2.0 913--> 914 915Returns a `object` that is the JSON representation of the 916`PerformanceResourceTiming` object 917 918## Class: `perf_hooks.PerformanceObserver` 919 920<!-- YAML 921added: v8.5.0 922--> 923 924### `PerformanceObserver.supportedEntryTypes` 925 926<!-- YAML 927added: v16.0.0 928--> 929 930* {string\[]} 931 932Get supported types. 933 934### `new PerformanceObserver(callback)` 935 936<!-- YAML 937added: v8.5.0 938changes: 939 - version: v18.0.0 940 pr-url: https://github.com/nodejs/node/pull/41678 941 description: Passing an invalid callback to the `callback` argument 942 now throws `ERR_INVALID_ARG_TYPE` instead of 943 `ERR_INVALID_CALLBACK`. 944--> 945 946* `callback` {Function} 947 * `list` {PerformanceObserverEntryList} 948 * `observer` {PerformanceObserver} 949 950`PerformanceObserver` objects provide notifications when new 951`PerformanceEntry` instances have been added to the Performance Timeline. 952 953```js 954const { 955 performance, 956 PerformanceObserver, 957} = require('node:perf_hooks'); 958 959const obs = new PerformanceObserver((list, observer) => { 960 console.log(list.getEntries()); 961 962 performance.clearMarks(); 963 performance.clearMeasures(); 964 observer.disconnect(); 965}); 966obs.observe({ entryTypes: ['mark'], buffered: true }); 967 968performance.mark('test'); 969``` 970 971Because `PerformanceObserver` instances introduce their own additional 972performance overhead, instances should not be left subscribed to notifications 973indefinitely. Users should disconnect observers as soon as they are no 974longer needed. 975 976The `callback` is invoked when a `PerformanceObserver` is 977notified about new `PerformanceEntry` instances. The callback receives a 978`PerformanceObserverEntryList` instance and a reference to the 979`PerformanceObserver`. 980 981### `performanceObserver.disconnect()` 982 983<!-- YAML 984added: v8.5.0 985--> 986 987Disconnects the `PerformanceObserver` instance from all notifications. 988 989### `performanceObserver.observe(options)` 990 991<!-- YAML 992added: v8.5.0 993changes: 994 - version: v16.7.0 995 pr-url: https://github.com/nodejs/node/pull/39297 996 description: Updated to conform to Performance Timeline Level 2. The 997 buffered option has been added back. 998 - version: v16.0.0 999 pr-url: https://github.com/nodejs/node/pull/37136 1000 description: Updated to conform to User Timing Level 3. The 1001 buffered option has been removed. 1002--> 1003 1004* `options` {Object} 1005 * `type` {string} A single {PerformanceEntry} type. Must not be given 1006 if `entryTypes` is already specified. 1007 * `entryTypes` {string\[]} An array of strings identifying the types of 1008 {PerformanceEntry} instances the observer is interested in. If not 1009 provided an error will be thrown. 1010 * `buffered` {boolean} If true, the observer callback is called with a 1011 list global `PerformanceEntry` buffered entries. If false, only 1012 `PerformanceEntry`s created after the time point are sent to the 1013 observer callback. **Default:** `false`. 1014 1015Subscribes the {PerformanceObserver} instance to notifications of new 1016{PerformanceEntry} instances identified either by `options.entryTypes` 1017or `options.type`: 1018 1019```js 1020const { 1021 performance, 1022 PerformanceObserver, 1023} = require('node:perf_hooks'); 1024 1025const obs = new PerformanceObserver((list, observer) => { 1026 // Called once asynchronously. `list` contains three items. 1027}); 1028obs.observe({ type: 'mark' }); 1029 1030for (let n = 0; n < 3; n++) 1031 performance.mark(`test${n}`); 1032``` 1033 1034## Class: `PerformanceObserverEntryList` 1035 1036<!-- YAML 1037added: v8.5.0 1038--> 1039 1040The `PerformanceObserverEntryList` class is used to provide access to the 1041`PerformanceEntry` instances passed to a `PerformanceObserver`. 1042The constructor of this class is not exposed to users. 1043 1044### `performanceObserverEntryList.getEntries()` 1045 1046<!-- YAML 1047added: v8.5.0 1048--> 1049 1050* Returns: {PerformanceEntry\[]} 1051 1052Returns a list of `PerformanceEntry` objects in chronological order 1053with respect to `performanceEntry.startTime`. 1054 1055```js 1056const { 1057 performance, 1058 PerformanceObserver, 1059} = require('node:perf_hooks'); 1060 1061const obs = new PerformanceObserver((perfObserverList, observer) => { 1062 console.log(perfObserverList.getEntries()); 1063 /** 1064 * [ 1065 * PerformanceEntry { 1066 * name: 'test', 1067 * entryType: 'mark', 1068 * startTime: 81.465639, 1069 * duration: 0 1070 * }, 1071 * PerformanceEntry { 1072 * name: 'meow', 1073 * entryType: 'mark', 1074 * startTime: 81.860064, 1075 * duration: 0 1076 * } 1077 * ] 1078 */ 1079 1080 performance.clearMarks(); 1081 performance.clearMeasures(); 1082 observer.disconnect(); 1083}); 1084obs.observe({ type: 'mark' }); 1085 1086performance.mark('test'); 1087performance.mark('meow'); 1088``` 1089 1090### `performanceObserverEntryList.getEntriesByName(name[, type])` 1091 1092<!-- YAML 1093added: v8.5.0 1094--> 1095 1096* `name` {string} 1097* `type` {string} 1098* Returns: {PerformanceEntry\[]} 1099 1100Returns a list of `PerformanceEntry` objects in chronological order 1101with respect to `performanceEntry.startTime` whose `performanceEntry.name` is 1102equal to `name`, and optionally, whose `performanceEntry.entryType` is equal to 1103`type`. 1104 1105```js 1106const { 1107 performance, 1108 PerformanceObserver, 1109} = require('node:perf_hooks'); 1110 1111const obs = new PerformanceObserver((perfObserverList, observer) => { 1112 console.log(perfObserverList.getEntriesByName('meow')); 1113 /** 1114 * [ 1115 * PerformanceEntry { 1116 * name: 'meow', 1117 * entryType: 'mark', 1118 * startTime: 98.545991, 1119 * duration: 0 1120 * } 1121 * ] 1122 */ 1123 console.log(perfObserverList.getEntriesByName('nope')); // [] 1124 1125 console.log(perfObserverList.getEntriesByName('test', 'mark')); 1126 /** 1127 * [ 1128 * PerformanceEntry { 1129 * name: 'test', 1130 * entryType: 'mark', 1131 * startTime: 63.518931, 1132 * duration: 0 1133 * } 1134 * ] 1135 */ 1136 console.log(perfObserverList.getEntriesByName('test', 'measure')); // [] 1137 1138 performance.clearMarks(); 1139 performance.clearMeasures(); 1140 observer.disconnect(); 1141}); 1142obs.observe({ entryTypes: ['mark', 'measure'] }); 1143 1144performance.mark('test'); 1145performance.mark('meow'); 1146``` 1147 1148### `performanceObserverEntryList.getEntriesByType(type)` 1149 1150<!-- YAML 1151added: v8.5.0 1152--> 1153 1154* `type` {string} 1155* Returns: {PerformanceEntry\[]} 1156 1157Returns a list of `PerformanceEntry` objects in chronological order 1158with respect to `performanceEntry.startTime` whose `performanceEntry.entryType` 1159is equal to `type`. 1160 1161```js 1162const { 1163 performance, 1164 PerformanceObserver, 1165} = require('node:perf_hooks'); 1166 1167const obs = new PerformanceObserver((perfObserverList, observer) => { 1168 console.log(perfObserverList.getEntriesByType('mark')); 1169 /** 1170 * [ 1171 * PerformanceEntry { 1172 * name: 'test', 1173 * entryType: 'mark', 1174 * startTime: 55.897834, 1175 * duration: 0 1176 * }, 1177 * PerformanceEntry { 1178 * name: 'meow', 1179 * entryType: 'mark', 1180 * startTime: 56.350146, 1181 * duration: 0 1182 * } 1183 * ] 1184 */ 1185 performance.clearMarks(); 1186 performance.clearMeasures(); 1187 observer.disconnect(); 1188}); 1189obs.observe({ type: 'mark' }); 1190 1191performance.mark('test'); 1192performance.mark('meow'); 1193``` 1194 1195## `perf_hooks.createHistogram([options])` 1196 1197<!-- YAML 1198added: 1199 - v15.9.0 1200 - v14.18.0 1201--> 1202 1203* `options` {Object} 1204 * `lowest` {number|bigint} The lowest discernible value. Must be an integer 1205 value greater than 0. **Default:** `1`. 1206 * `highest` {number|bigint} The highest recordable value. Must be an integer 1207 value that is equal to or greater than two times `lowest`. 1208 **Default:** `Number.MAX_SAFE_INTEGER`. 1209 * `figures` {number} The number of accuracy digits. Must be a number between 1210 `1` and `5`. **Default:** `3`. 1211* Returns {RecordableHistogram} 1212 1213Returns a {RecordableHistogram}. 1214 1215## `perf_hooks.monitorEventLoopDelay([options])` 1216 1217<!-- YAML 1218added: v11.10.0 1219--> 1220 1221* `options` {Object} 1222 * `resolution` {number} The sampling rate in milliseconds. Must be greater 1223 than zero. **Default:** `10`. 1224* Returns: {IntervalHistogram} 1225 1226_This property is an extension by Node.js. It is not available in Web browsers._ 1227 1228Creates an `IntervalHistogram` object that samples and reports the event loop 1229delay over time. The delays will be reported in nanoseconds. 1230 1231Using a timer to detect approximate event loop delay works because the 1232execution of timers is tied specifically to the lifecycle of the libuv 1233event loop. That is, a delay in the loop will cause a delay in the execution 1234of the timer, and those delays are specifically what this API is intended to 1235detect. 1236 1237```js 1238const { monitorEventLoopDelay } = require('node:perf_hooks'); 1239const h = monitorEventLoopDelay({ resolution: 20 }); 1240h.enable(); 1241// Do something. 1242h.disable(); 1243console.log(h.min); 1244console.log(h.max); 1245console.log(h.mean); 1246console.log(h.stddev); 1247console.log(h.percentiles); 1248console.log(h.percentile(50)); 1249console.log(h.percentile(99)); 1250``` 1251 1252## Class: `Histogram` 1253 1254<!-- YAML 1255added: v11.10.0 1256--> 1257 1258### `histogram.count` 1259 1260<!-- YAML 1261added: 1262 - v17.4.0 1263 - v16.14.0 1264--> 1265 1266* {number} 1267 1268The number of samples recorded by the histogram. 1269 1270### `histogram.countBigInt` 1271 1272<!-- YAML 1273added: 1274 - v17.4.0 1275 - v16.14.0 1276--> 1277 1278* {bigint} 1279 1280The number of samples recorded by the histogram. 1281 1282### `histogram.exceeds` 1283 1284<!-- YAML 1285added: v11.10.0 1286--> 1287 1288* {number} 1289 1290The number of times the event loop delay exceeded the maximum 1 hour event 1291loop delay threshold. 1292 1293### `histogram.exceedsBigInt` 1294 1295<!-- YAML 1296added: 1297 - v17.4.0 1298 - v16.14.0 1299--> 1300 1301* {bigint} 1302 1303The number of times the event loop delay exceeded the maximum 1 hour event 1304loop delay threshold. 1305 1306### `histogram.max` 1307 1308<!-- YAML 1309added: v11.10.0 1310--> 1311 1312* {number} 1313 1314The maximum recorded event loop delay. 1315 1316### `histogram.maxBigInt` 1317 1318<!-- YAML 1319added: 1320 - v17.4.0 1321 - v16.14.0 1322--> 1323 1324* {bigint} 1325 1326The maximum recorded event loop delay. 1327 1328### `histogram.mean` 1329 1330<!-- YAML 1331added: v11.10.0 1332--> 1333 1334* {number} 1335 1336The mean of the recorded event loop delays. 1337 1338### `histogram.min` 1339 1340<!-- YAML 1341added: v11.10.0 1342--> 1343 1344* {number} 1345 1346The minimum recorded event loop delay. 1347 1348### `histogram.minBigInt` 1349 1350<!-- YAML 1351added: 1352 - v17.4.0 1353 - v16.14.0 1354--> 1355 1356* {bigint} 1357 1358The minimum recorded event loop delay. 1359 1360### `histogram.percentile(percentile)` 1361 1362<!-- YAML 1363added: v11.10.0 1364--> 1365 1366* `percentile` {number} A percentile value in the range (0, 100]. 1367* Returns: {number} 1368 1369Returns the value at the given percentile. 1370 1371### `histogram.percentileBigInt(percentile)` 1372 1373<!-- YAML 1374added: 1375 - v17.4.0 1376 - v16.14.0 1377--> 1378 1379* `percentile` {number} A percentile value in the range (0, 100]. 1380* Returns: {bigint} 1381 1382Returns the value at the given percentile. 1383 1384### `histogram.percentiles` 1385 1386<!-- YAML 1387added: v11.10.0 1388--> 1389 1390* {Map} 1391 1392Returns a `Map` object detailing the accumulated percentile distribution. 1393 1394### `histogram.percentilesBigInt` 1395 1396<!-- YAML 1397added: 1398 - v17.4.0 1399 - v16.14.0 1400--> 1401 1402* {Map} 1403 1404Returns a `Map` object detailing the accumulated percentile distribution. 1405 1406### `histogram.reset()` 1407 1408<!-- YAML 1409added: v11.10.0 1410--> 1411 1412Resets the collected histogram data. 1413 1414### `histogram.stddev` 1415 1416<!-- YAML 1417added: v11.10.0 1418--> 1419 1420* {number} 1421 1422The standard deviation of the recorded event loop delays. 1423 1424## Class: `IntervalHistogram extends Histogram` 1425 1426A `Histogram` that is periodically updated on a given interval. 1427 1428### `histogram.disable()` 1429 1430<!-- YAML 1431added: v11.10.0 1432--> 1433 1434* Returns: {boolean} 1435 1436Disables the update interval timer. Returns `true` if the timer was 1437stopped, `false` if it was already stopped. 1438 1439### `histogram.enable()` 1440 1441<!-- YAML 1442added: v11.10.0 1443--> 1444 1445* Returns: {boolean} 1446 1447Enables the update interval timer. Returns `true` if the timer was 1448started, `false` if it was already started. 1449 1450### Cloning an `IntervalHistogram` 1451 1452{IntervalHistogram} instances can be cloned via {MessagePort}. On the receiving 1453end, the histogram is cloned as a plain {Histogram} object that does not 1454implement the `enable()` and `disable()` methods. 1455 1456## Class: `RecordableHistogram extends Histogram` 1457 1458<!-- YAML 1459added: 1460 - v15.9.0 1461 - v14.18.0 1462--> 1463 1464### `histogram.add(other)` 1465 1466<!-- YAML 1467added: 1468 - v17.4.0 1469 - v16.14.0 1470--> 1471 1472* `other` {RecordableHistogram} 1473 1474Adds the values from `other` to this histogram. 1475 1476### `histogram.record(val)` 1477 1478<!-- YAML 1479added: 1480 - v15.9.0 1481 - v14.18.0 1482--> 1483 1484* `val` {number|bigint} The amount to record in the histogram. 1485 1486### `histogram.recordDelta()` 1487 1488<!-- YAML 1489added: 1490 - v15.9.0 1491 - v14.18.0 1492--> 1493 1494Calculates the amount of time (in nanoseconds) that has passed since the 1495previous call to `recordDelta()` and records that amount in the histogram. 1496 1497## Examples 1498 1499### Measuring the duration of async operations 1500 1501The following example uses the [Async Hooks][] and Performance APIs to measure 1502the actual duration of a Timeout operation (including the amount of time it took 1503to execute the callback). 1504 1505```js 1506'use strict'; 1507const async_hooks = require('node:async_hooks'); 1508const { 1509 performance, 1510 PerformanceObserver, 1511} = require('node:perf_hooks'); 1512 1513const set = new Set(); 1514const hook = async_hooks.createHook({ 1515 init(id, type) { 1516 if (type === 'Timeout') { 1517 performance.mark(`Timeout-${id}-Init`); 1518 set.add(id); 1519 } 1520 }, 1521 destroy(id) { 1522 if (set.has(id)) { 1523 set.delete(id); 1524 performance.mark(`Timeout-${id}-Destroy`); 1525 performance.measure(`Timeout-${id}`, 1526 `Timeout-${id}-Init`, 1527 `Timeout-${id}-Destroy`); 1528 } 1529 }, 1530}); 1531hook.enable(); 1532 1533const obs = new PerformanceObserver((list, observer) => { 1534 console.log(list.getEntries()[0]); 1535 performance.clearMarks(); 1536 performance.clearMeasures(); 1537 observer.disconnect(); 1538}); 1539obs.observe({ entryTypes: ['measure'], buffered: true }); 1540 1541setTimeout(() => {}, 1000); 1542``` 1543 1544### Measuring how long it takes to load dependencies 1545 1546The following example measures the duration of `require()` operations to load 1547dependencies: 1548 1549<!-- eslint-disable no-global-assign --> 1550 1551```js 1552'use strict'; 1553const { 1554 performance, 1555 PerformanceObserver, 1556} = require('node:perf_hooks'); 1557const mod = require('node:module'); 1558 1559// Monkey patch the require function 1560mod.Module.prototype.require = 1561 performance.timerify(mod.Module.prototype.require); 1562require = performance.timerify(require); 1563 1564// Activate the observer 1565const obs = new PerformanceObserver((list) => { 1566 const entries = list.getEntries(); 1567 entries.forEach((entry) => { 1568 console.log(`require('${entry[0]}')`, entry.duration); 1569 }); 1570 performance.clearMarks(); 1571 performance.clearMeasures(); 1572 obs.disconnect(); 1573}); 1574obs.observe({ entryTypes: ['function'], buffered: true }); 1575 1576require('some-module'); 1577``` 1578 1579### Measuring how long one HTTP round-trip takes 1580 1581The following example is used to trace the time spent by HTTP client 1582(`OutgoingMessage`) and HTTP request (`IncomingMessage`). For HTTP client, 1583it means the time interval between starting the request and receiving the 1584response, and for HTTP request, it means the time interval between receiving 1585the request and sending the response: 1586 1587```js 1588'use strict'; 1589const { PerformanceObserver } = require('node:perf_hooks'); 1590const http = require('node:http'); 1591 1592const obs = new PerformanceObserver((items) => { 1593 items.getEntries().forEach((item) => { 1594 console.log(item); 1595 }); 1596}); 1597 1598obs.observe({ entryTypes: ['http'] }); 1599 1600const PORT = 8080; 1601 1602http.createServer((req, res) => { 1603 res.end('ok'); 1604}).listen(PORT, () => { 1605 http.get(`http://127.0.0.1:${PORT}`); 1606}); 1607``` 1608 1609### Measuring how long the `net.connect` (only for TCP) takes when the connection is successful 1610 1611```js 1612'use strict'; 1613const { PerformanceObserver } = require('node:perf_hooks'); 1614const net = require('node:net'); 1615const obs = new PerformanceObserver((items) => { 1616 items.getEntries().forEach((item) => { 1617 console.log(item); 1618 }); 1619}); 1620obs.observe({ entryTypes: ['net'] }); 1621const PORT = 8080; 1622net.createServer((socket) => { 1623 socket.destroy(); 1624}).listen(PORT, () => { 1625 net.connect(PORT); 1626}); 1627``` 1628 1629### Measuring how long the DNS takes when the request is successful 1630 1631```js 1632'use strict'; 1633const { PerformanceObserver } = require('node:perf_hooks'); 1634const dns = require('node:dns'); 1635const obs = new PerformanceObserver((items) => { 1636 items.getEntries().forEach((item) => { 1637 console.log(item); 1638 }); 1639}); 1640obs.observe({ entryTypes: ['dns'] }); 1641dns.lookup('localhost', () => {}); 1642dns.promises.resolve('localhost'); 1643``` 1644 1645[Async Hooks]: async_hooks.md 1646[Fetch Timing Info]: https://fetch.spec.whatwg.org/#fetch-timing-info 1647[High Resolution Time]: https://www.w3.org/TR/hr-time-2 1648[Performance Timeline]: https://w3c.github.io/performance-timeline/ 1649[Resource Timing]: https://www.w3.org/TR/resource-timing-2/ 1650[User Timing]: https://www.w3.org/TR/user-timing/ 1651[Web Performance APIs]: https://w3c.github.io/perf-timing-primer/ 1652[Worker threads]: worker_threads.md#worker-threads 1653[`'exit'`]: process.md#event-exit 1654[`child_process.spawnSync()`]: child_process.md#child_processspawnsynccommand-args-options 1655[`process.hrtime()`]: process.md#processhrtimetime 1656[`timeOrigin`]: https://w3c.github.io/hr-time/#dom-performance-timeorigin 1657[`window.performance.toJSON`]: https://developer.mozilla.org/en-US/docs/Web/API/Performance/toJSON 1658[`window.performance`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/performance 1659