1# Worker threads 2 3<!--introduced_in=v10.5.0--> 4 5> Stability: 2 - Stable 6 7<!-- source_link=lib/worker_threads.js --> 8 9The `worker_threads` module enables the use of threads that execute JavaScript 10in parallel. To access it: 11 12```js 13const worker = require('worker_threads'); 14``` 15 16Workers (threads) are useful for performing CPU-intensive JavaScript operations. 17They will not help much with I/O-intensive work. Node.js’s built-in asynchronous 18I/O operations are more efficient than Workers can be. 19 20Unlike `child_process` or `cluster`, `worker_threads` can share memory. They do 21so by transferring `ArrayBuffer` instances or sharing `SharedArrayBuffer` 22instances. 23 24```js 25const { 26 Worker, isMainThread, parentPort, workerData 27} = require('worker_threads'); 28 29if (isMainThread) { 30 module.exports = function parseJSAsync(script) { 31 return new Promise((resolve, reject) => { 32 const worker = new Worker(__filename, { 33 workerData: script 34 }); 35 worker.on('message', resolve); 36 worker.on('error', reject); 37 worker.on('exit', (code) => { 38 if (code !== 0) 39 reject(new Error(`Worker stopped with exit code ${code}`)); 40 }); 41 }); 42 }; 43} else { 44 const { parse } = require('some-js-parsing-library'); 45 const script = workerData; 46 parentPort.postMessage(parse(script)); 47} 48``` 49 50The above example spawns a Worker thread for each `parse()` call. In actual 51practice, use a pool of Workers instead for these kinds of tasks. Otherwise, the 52overhead of creating Workers would likely exceed their benefit. 53 54When implementing a worker pool, use the [`AsyncResource`][] API to inform 55diagnostic tools (e.g. in order to provide asynchronous stack traces) about the 56correlation between tasks and their outcomes. See 57["Using `AsyncResource` for a `Worker` thread pool"][async-resource-worker-pool] 58in the `async_hooks` documentation for an example implementation. 59 60Worker threads inherit non-process-specific options by default. Refer to 61[`Worker constructor options`][] to know how to customize worker thread options, 62specifically `argv` and `execArgv` options. 63 64## `worker.getEnvironmentData(key)` 65<!-- YAML 66added: v14.18.0 67--> 68 69> Stability: 1 - Experimental 70 71* `key` {any} Any arbitrary, cloneable JavaScript value that can be used as a 72 {Map} key. 73* Returns: {any} 74 75Within a worker thread, `worker.getEnvironmentData()` returns a clone 76of data passed to the spawning thread's `worker.setEnvironmentData()`. 77Every new `Worker` receives its own copy of the environment data 78automatically. 79 80```js 81const { 82 Worker, 83 isMainThread, 84 setEnvironmentData, 85 getEnvironmentData, 86} = require('worker_threads'); 87 88if (isMainThread) { 89 setEnvironmentData('Hello', 'World!'); 90 const worker = new Worker(__filename); 91} else { 92 console.log(getEnvironmentData('Hello')); // Prints 'World!'. 93} 94``` 95 96## `worker.isMainThread` 97<!-- YAML 98added: v10.5.0 99--> 100 101* {boolean} 102 103Is `true` if this code is not running inside of a [`Worker`][] thread. 104 105```js 106const { Worker, isMainThread } = require('worker_threads'); 107 108if (isMainThread) { 109 // This re-loads the current file inside a Worker instance. 110 new Worker(__filename); 111} else { 112 console.log('Inside Worker!'); 113 console.log(isMainThread); // Prints 'false'. 114} 115``` 116 117## `worker.markAsUntransferable(object)` 118<!-- YAML 119added: v14.5.0 120--> 121 122Mark an object as not transferable. If `object` occurs in the transfer list of 123a [`port.postMessage()`][] call, it will be ignored. 124 125In particular, this makes sense for objects that can be cloned, rather than 126transferred, and which are used by other objects on the sending side. 127For example, Node.js marks the `ArrayBuffer`s it uses for its 128[`Buffer` pool][`Buffer.allocUnsafe()`] with this. 129 130This operation cannot be undone. 131 132```js 133const { MessageChannel, markAsUntransferable } = require('worker_threads'); 134 135const pooledBuffer = new ArrayBuffer(8); 136const typedArray1 = new Uint8Array(pooledBuffer); 137const typedArray2 = new Float64Array(pooledBuffer); 138 139markAsUntransferable(pooledBuffer); 140 141const { port1 } = new MessageChannel(); 142port1.postMessage(typedArray1, [ typedArray1.buffer ]); 143 144// The following line prints the contents of typedArray1 -- it still owns 145// its memory and has been cloned, not transferred. Without 146// `markAsUntransferable()`, this would print an empty Uint8Array. 147// typedArray2 is intact as well. 148console.log(typedArray1); 149console.log(typedArray2); 150``` 151 152There is no equivalent to this API in browsers. 153 154## `worker.moveMessagePortToContext(port, contextifiedSandbox)` 155<!-- YAML 156added: v11.13.0 157--> 158 159* `port` {MessagePort} The message port which will be transferred. 160* `contextifiedSandbox` {Object} A [contextified][] object as returned by the 161 `vm.createContext()` method. 162 163* Returns: {MessagePort} 164 165Transfer a `MessagePort` to a different [`vm`][] Context. The original `port` 166object will be rendered unusable, and the returned `MessagePort` instance will 167take its place. 168 169The returned `MessagePort` will be an object in the target context, and will 170inherit from its global `Object` class. Objects passed to the 171[`port.onmessage()`][] listener will also be created in the target context 172and inherit from its global `Object` class. 173 174However, the created `MessagePort` will no longer inherit from 175[`EventTarget`][], and only [`port.onmessage()`][] can be used to receive 176events using it. 177 178## `worker.parentPort` 179<!-- YAML 180added: v10.5.0 181--> 182 183* {null|MessagePort} 184 185If this thread was spawned as a [`Worker`][], this will be a [`MessagePort`][] 186allowing communication with the parent thread. Messages sent using 187`parentPort.postMessage()` will be available in the parent thread 188using `worker.on('message')`, and messages sent from the parent thread 189using `worker.postMessage()` will be available in this thread using 190`parentPort.on('message')`. 191 192```js 193const { Worker, isMainThread, parentPort } = require('worker_threads'); 194 195if (isMainThread) { 196 const worker = new Worker(__filename); 197 worker.once('message', (message) => { 198 console.log(message); // Prints 'Hello, world!'. 199 }); 200 worker.postMessage('Hello, world!'); 201} else { 202 // When a message from the parent thread is received, send it back: 203 parentPort.once('message', (message) => { 204 parentPort.postMessage(message); 205 }); 206} 207``` 208 209## `worker.receiveMessageOnPort(port)` 210<!-- YAML 211added: v12.3.0 212--> 213 214* `port` {MessagePort} 215 216* Returns: {Object|undefined} 217 218Receive a single message from a given `MessagePort`. If no message is available, 219`undefined` is returned, otherwise an object with a single `message` property 220that contains the message payload, corresponding to the oldest message in the 221`MessagePort`’s queue. 222 223```js 224const { MessageChannel, receiveMessageOnPort } = require('worker_threads'); 225const { port1, port2 } = new MessageChannel(); 226port1.postMessage({ hello: 'world' }); 227 228console.log(receiveMessageOnPort(port2)); 229// Prints: { message: { hello: 'world' } } 230console.log(receiveMessageOnPort(port2)); 231// Prints: undefined 232``` 233 234When this function is used, no `'message'` event will be emitted and the 235`onmessage` listener will not be invoked. 236 237## `worker.resourceLimits` 238<!-- YAML 239added: 240 - v13.2.0 241 - v12.16.0 242--> 243 244* {Object} 245 * `maxYoungGenerationSizeMb` {number} 246 * `maxOldGenerationSizeMb` {number} 247 * `codeRangeSizeMb` {number} 248 * `stackSizeMb` {number} 249 250Provides the set of JS engine resource constraints inside this Worker thread. 251If the `resourceLimits` option was passed to the [`Worker`][] constructor, 252this matches its values. 253 254If this is used in the main thread, its value is an empty object. 255 256## `worker.SHARE_ENV` 257<!-- YAML 258added: v11.14.0 259--> 260 261* {symbol} 262 263A special value that can be passed as the `env` option of the [`Worker`][] 264constructor, to indicate that the current thread and the Worker thread should 265share read and write access to the same set of environment variables. 266 267```js 268const { Worker, SHARE_ENV } = require('worker_threads'); 269new Worker('process.env.SET_IN_WORKER = "foo"', { eval: true, env: SHARE_ENV }) 270 .on('exit', () => { 271 console.log(process.env.SET_IN_WORKER); // Prints 'foo'. 272 }); 273``` 274 275## `worker.setEnvironmentData(key[, value])` 276<!-- YAML 277added: v14.18.0 278--> 279 280> Stability: 1 - Experimental 281 282* `key` {any} Any arbitrary, cloneable JavaScript value that can be used as a 283 {Map} key. 284* `value` {any} Any arbitrary, cloneable JavaScript value that will be cloned 285 and passed automatically to all new `Worker` instances. If `value` is passed 286 as `undefined`, any previously set value for the `key` will be deleted. 287 288The `worker.setEnvironmentData()` API sets the content of 289`worker.getEnvironmentData()` in the current thread and all new `Worker` 290instances spawned from the current context. 291 292## `worker.threadId` 293<!-- YAML 294added: v10.5.0 295--> 296 297* {integer} 298 299An integer identifier for the current thread. On the corresponding worker object 300(if there is any), it is available as [`worker.threadId`][]. 301This value is unique for each [`Worker`][] instance inside a single process. 302 303## `worker.workerData` 304<!-- YAML 305added: v10.5.0 306--> 307 308An arbitrary JavaScript value that contains a clone of the data passed 309to this thread’s `Worker` constructor. 310 311The data is cloned as if using [`postMessage()`][`port.postMessage()`], 312according to the [HTML structured clone algorithm][]. 313 314```js 315const { Worker, isMainThread, workerData } = require('worker_threads'); 316 317if (isMainThread) { 318 const worker = new Worker(__filename, { workerData: 'Hello, world!' }); 319} else { 320 console.log(workerData); // Prints 'Hello, world!'. 321} 322``` 323 324## Class: `MessageChannel` 325<!-- YAML 326added: v10.5.0 327--> 328 329Instances of the `worker.MessageChannel` class represent an asynchronous, 330two-way communications channel. 331The `MessageChannel` has no methods of its own. `new MessageChannel()` 332yields an object with `port1` and `port2` properties, which refer to linked 333[`MessagePort`][] instances. 334 335```js 336const { MessageChannel } = require('worker_threads'); 337 338const { port1, port2 } = new MessageChannel(); 339port1.on('message', (message) => console.log('received', message)); 340port2.postMessage({ foo: 'bar' }); 341// Prints: received { foo: 'bar' } from the `port1.on('message')` listener 342``` 343 344## Class: `MessagePort` 345<!-- YAML 346added: v10.5.0 347changes: 348 - version: 349 - v14.7.0 350 pr-url: https://github.com/nodejs/node/pull/34057 351 description: This class now inherits from `EventTarget` rather than 352 from `EventEmitter`. 353--> 354 355* Extends: {EventTarget} 356 357Instances of the `worker.MessagePort` class represent one end of an 358asynchronous, two-way communications channel. It can be used to transfer 359structured data, memory regions and other `MessagePort`s between different 360[`Worker`][]s. 361 362This implementation matches [browser `MessagePort`][]s. 363 364### Event: `'close'` 365<!-- YAML 366added: v10.5.0 367--> 368 369The `'close'` event is emitted once either side of the channel has been 370disconnected. 371 372```js 373const { MessageChannel } = require('worker_threads'); 374const { port1, port2 } = new MessageChannel(); 375 376// Prints: 377// foobar 378// closed! 379port2.on('message', (message) => console.log(message)); 380port2.on('close', () => console.log('closed!')); 381 382port1.postMessage('foobar'); 383port1.close(); 384``` 385 386### Event: `'message'` 387<!-- YAML 388added: v10.5.0 389--> 390 391* `value` {any} The transmitted value 392 393The `'message'` event is emitted for any incoming message, containing the cloned 394input of [`port.postMessage()`][]. 395 396Listeners on this event will receive a clone of the `value` parameter as passed 397to `postMessage()` and no further arguments. 398 399### Event: `'messageerror'` 400<!-- YAML 401added: v14.5.0 402--> 403 404* `error` {Error} An Error object 405 406The `'messageerror'` event is emitted when deserializing a message failed. 407 408Currently, this event is emitted when there is an error occurring while 409instantiating the posted JS object on the receiving end. Such situations 410are rare, but can happen, for instance, when certain Node.js API objects 411are received in a `vm.Context` (where Node.js APIs are currently 412unavailable). 413 414### `port.close()` 415<!-- YAML 416added: v10.5.0 417--> 418 419Disables further sending of messages on either side of the connection. 420This method can be called when no further communication will happen over this 421`MessagePort`. 422 423The [`'close'` event][] will be emitted on both `MessagePort` instances that 424are part of the channel. 425 426### `port.postMessage(value[, transferList])` 427<!-- YAML 428added: v10.5.0 429changes: 430 - version: v14.18.0 431 pr-url: https://github.com/nodejs/node/pull/37917 432 description: Add 'BlockList' to the list of cloneable types. 433 - version: v14.18.0 434 pr-url: https://github.com/nodejs/node/pull/37155 435 description: Add 'Histogram' types to the list of cloneable types. 436 - version: v14.5.0 437 pr-url: https://github.com/nodejs/node/pull/33360 438 description: Added `KeyObject` to the list of cloneable types. 439 - version: v14.5.0 440 pr-url: https://github.com/nodejs/node/pull/33772 441 description: Added `FileHandle` to the list of transferable types. 442--> 443 444* `value` {any} 445* `transferList` {Object[]} 446 447Sends a JavaScript value to the receiving side of this channel. 448`value` will be transferred in a way which is compatible with 449the [HTML structured clone algorithm][]. 450 451In particular, the significant differences to `JSON` are: 452 453* `value` may contain circular references. 454* `value` may contain instances of builtin JS types such as `RegExp`s, 455 `BigInt`s, `Map`s, `Set`s, etc. 456* `value` may contain typed arrays, both using `ArrayBuffer`s 457 and `SharedArrayBuffer`s. 458* `value` may contain [`WebAssembly.Module`][] instances. 459* `value` may not contain native (C++-backed) objects other than: 460 * {FileHandle}s, 461 * {Histogram}s, 462 * {KeyObject}s, 463 * {MessagePort}s, 464 * {net.BlockList}s, 465 * {net.SocketAddress}es, 466 467```js 468const { MessageChannel } = require('worker_threads'); 469const { port1, port2 } = new MessageChannel(); 470 471port1.on('message', (message) => console.log(message)); 472 473const circularData = {}; 474circularData.foo = circularData; 475// Prints: { foo: [Circular] } 476port2.postMessage(circularData); 477``` 478 479`transferList` may be a list of [`ArrayBuffer`][], [`MessagePort`][] and 480[`FileHandle`][] objects. 481After transferring, they will not be usable on the sending side of the channel 482anymore (even if they are not contained in `value`). Unlike with 483[child processes][], transferring handles such as network sockets is currently 484not supported. 485 486If `value` contains [`SharedArrayBuffer`][] instances, those will be accessible 487from either thread. They cannot be listed in `transferList`. 488 489`value` may still contain `ArrayBuffer` instances that are not in 490`transferList`; in that case, the underlying memory is copied rather than moved. 491 492```js 493const { MessageChannel } = require('worker_threads'); 494const { port1, port2 } = new MessageChannel(); 495 496port1.on('message', (message) => console.log(message)); 497 498const uint8Array = new Uint8Array([ 1, 2, 3, 4 ]); 499// This posts a copy of `uint8Array`: 500port2.postMessage(uint8Array); 501// This does not copy data, but renders `uint8Array` unusable: 502port2.postMessage(uint8Array, [ uint8Array.buffer ]); 503 504// The memory for the `sharedUint8Array` will be accessible from both the 505// original and the copy received by `.on('message')`: 506const sharedUint8Array = new Uint8Array(new SharedArrayBuffer(4)); 507port2.postMessage(sharedUint8Array); 508 509// This transfers a freshly created message port to the receiver. 510// This can be used, for example, to create communication channels between 511// multiple `Worker` threads that are children of the same parent thread. 512const otherChannel = new MessageChannel(); 513port2.postMessage({ port: otherChannel.port1 }, [ otherChannel.port1 ]); 514``` 515 516Because the object cloning uses the structured clone algorithm, 517non-enumerable properties, property accessors, and object prototypes are 518not preserved. In particular, [`Buffer`][] objects will be read as 519plain [`Uint8Array`][]s on the receiving side. 520 521The message object will be cloned immediately, and can be modified after 522posting without having side effects. 523 524For more information on the serialization and deserialization mechanisms 525behind this API, see the [serialization API of the `v8` module][v8.serdes]. 526 527#### Considerations when transferring TypedArrays and Buffers 528 529All `TypedArray` and `Buffer` instances are views over an underlying 530`ArrayBuffer`. That is, it is the `ArrayBuffer` that actually stores 531the raw data while the `TypedArray` and `Buffer` objects provide a 532way of viewing and manipulating the data. It is possible and common 533for multiple views to be created over the same `ArrayBuffer` instance. 534Great care must be taken when using a transfer list to transfer an 535`ArrayBuffer` as doing so will cause all `TypedArray` and `Buffer` 536instances that share that same `ArrayBuffer` to become unusable. 537 538```js 539const ab = new ArrayBuffer(10); 540 541const u1 = new Uint8Array(ab); 542const u2 = new Uint16Array(ab); 543 544console.log(u2.length); // prints 5 545 546port.postMessage(u1, [u1.buffer]); 547 548console.log(u2.length); // prints 0 549``` 550 551For `Buffer` instances, specifically, whether the underlying 552`ArrayBuffer` can be transferred or cloned depends entirely on how 553instances were created, which often cannot be reliably determined. 554 555An `ArrayBuffer` can be marked with [`markAsUntransferable()`][] to indicate 556that it should always be cloned and never transferred. 557 558Depending on how a `Buffer` instance was created, it may or may 559not own its underlying `ArrayBuffer`. An `ArrayBuffer` must not 560be transferred unless it is known that the `Buffer` instance 561owns it. In particular, for `Buffer`s created from the internal 562`Buffer` pool (using, for instance `Buffer.from()` or `Buffer.alloc()`), 563transferring them is not possible and they will always be cloned, 564which sends a copy of the entire `Buffer` pool. 565This behavior may come with unintended higher memory 566usage and possible security concerns. 567 568See [`Buffer.allocUnsafe()`][] for more details on `Buffer` pooling. 569 570The `ArrayBuffer`s for `Buffer` instances created using 571`Buffer.alloc()` or `Buffer.allocUnsafeSlow()` can always be 572transferred but doing so will render all other existing views of 573those `ArrayBuffer`s unusable. 574 575### `port.ref()` 576<!-- YAML 577added: v10.5.0 578--> 579 580Opposite of `unref()`. Calling `ref()` on a previously `unref()`ed port will 581*not* let the program exit if it's the only active handle left (the default 582behavior). If the port is `ref()`ed, calling `ref()` again will have no effect. 583 584If listeners are attached or removed using `.on('message')`, the port will 585be `ref()`ed and `unref()`ed automatically depending on whether 586listeners for the event exist. 587 588### `port.start()` 589<!-- YAML 590added: v10.5.0 591--> 592 593Starts receiving messages on this `MessagePort`. When using this port 594as an event emitter, this will be called automatically once `'message'` 595listeners are attached. 596 597This method exists for parity with the Web `MessagePort` API. In Node.js, 598it is only useful for ignoring messages when no event listener is present. 599Node.js also diverges in its handling of `.onmessage`. Setting it will 600automatically call `.start()`, but unsetting it will let messages queue up 601until a new handler is set or the port is discarded. 602 603### `port.unref()` 604<!-- YAML 605added: v10.5.0 606--> 607 608Calling `unref()` on a port will allow the thread to exit if this is the only 609active handle in the event system. If the port is already `unref()`ed calling 610`unref()` again will have no effect. 611 612If listeners are attached or removed using `.on('message')`, the port will 613be `ref()`ed and `unref()`ed automatically depending on whether 614listeners for the event exist. 615 616## Class: `Worker` 617<!-- YAML 618added: v10.5.0 619--> 620 621* Extends: {EventEmitter} 622 623The `Worker` class represents an independent JavaScript execution thread. 624Most Node.js APIs are available inside of it. 625 626Notable differences inside a Worker environment are: 627 628* The [`process.stdin`][], [`process.stdout`][] and [`process.stderr`][] 629 may be redirected by the parent thread. 630* The [`require('worker_threads').isMainThread`][] property is set to `false`. 631* The [`require('worker_threads').parentPort`][] message port is available. 632* [`process.exit()`][] does not stop the whole program, just the single thread, 633 and [`process.abort()`][] is not available. 634* [`process.chdir()`][] and `process` methods that set group or user ids 635 are not available. 636* [`process.env`][] is a copy of the parent thread's environment variables, 637 unless otherwise specified. Changes to one copy will not be visible in other 638 threads, and will not be visible to native add-ons (unless 639 [`worker.SHARE_ENV`][] has been passed as the `env` option to the 640 [`Worker`][] constructor). 641* [`process.title`][] cannot be modified. 642* Signals will not be delivered through [`process.on('...')`][Signals events]. 643* Execution may stop at any point as a result of [`worker.terminate()`][] 644 being invoked. 645* IPC channels from parent processes are not accessible. 646* The [`trace_events`][] module is not supported. 647* Native add-ons can only be loaded from multiple threads if they fulfill 648 [certain conditions][Addons worker support]. 649 650Creating `Worker` instances inside of other `Worker`s is possible. 651 652Like [Web Workers][] and the [`cluster` module][], two-way communication can be 653achieved through inter-thread message passing. Internally, a `Worker` has a 654built-in pair of [`MessagePort`][]s that are already associated with each other 655when the `Worker` is created. While the `MessagePort` object on the parent side 656is not directly exposed, its functionalities are exposed through 657[`worker.postMessage()`][] and the [`worker.on('message')`][] event 658on the `Worker` object for the parent thread. 659 660To create custom messaging channels (which is encouraged over using the default 661global channel because it facilitates separation of concerns), users can create 662a `MessageChannel` object on either thread and pass one of the 663`MessagePort`s on that `MessageChannel` to the other thread through a 664pre-existing channel, such as the global one. 665 666See [`port.postMessage()`][] for more information on how messages are passed, 667and what kind of JavaScript values can be successfully transported through 668the thread barrier. 669 670```js 671const assert = require('assert'); 672const { 673 Worker, MessageChannel, MessagePort, isMainThread, parentPort 674} = require('worker_threads'); 675if (isMainThread) { 676 const worker = new Worker(__filename); 677 const subChannel = new MessageChannel(); 678 worker.postMessage({ hereIsYourPort: subChannel.port1 }, [subChannel.port1]); 679 subChannel.port2.on('message', (value) => { 680 console.log('received:', value); 681 }); 682} else { 683 parentPort.once('message', (value) => { 684 assert(value.hereIsYourPort instanceof MessagePort); 685 value.hereIsYourPort.postMessage('the worker is sending this'); 686 value.hereIsYourPort.close(); 687 }); 688} 689``` 690 691### `new Worker(filename[, options])` 692<!-- YAML 693added: v10.5.0 694changes: 695 - version: v14.9.0 696 pr-url: https://github.com/nodejs/node/pull/34584 697 description: The `filename` parameter can be a WHATWG `URL` object using 698 `data:` protocol. 699 - version: v14.9.0 700 pr-url: https://github.com/nodejs/node/pull/34394 701 description: The `trackUnmanagedFds` option was set to `true` by default. 702 - version: 703 - v14.6.0 704 pr-url: https://github.com/nodejs/node/pull/34303 705 description: The `trackUnmanagedFds` option was introduced. 706 - version: v14.0.0 707 pr-url: https://github.com/nodejs/node/pull/32278 708 description: The `transferList` option was introduced. 709 - version: v13.12.0 710 pr-url: https://github.com/nodejs/node/pull/31664 711 description: The `filename` parameter can be a WHATWG `URL` object using 712 `file:` protocol. 713 - version: 714 - v13.4.0 715 - v12.16.0 716 pr-url: https://github.com/nodejs/node/pull/30559 717 description: The `argv` option was introduced. 718 - version: 719 - v13.2.0 720 - v12.16.0 721 pr-url: https://github.com/nodejs/node/pull/26628 722 description: The `resourceLimits` option was introduced. 723--> 724 725* `filename` {string|URL} The path to the Worker’s main script or module. Must 726 be either an absolute path or a relative path (i.e. relative to the 727 current working directory) starting with `./` or `../`, or a WHATWG `URL` 728 object using `file:` or `data:` protocol. 729 When using a [`data:` URL][], the data is interpreted based on MIME type using 730 the [ECMAScript module loader][]. 731 If `options.eval` is `true`, this is a string containing JavaScript code 732 rather than a path. 733* `options` {Object} 734 * `argv` {any[]} List of arguments which would be stringified and appended to 735 `process.argv` in the worker. This is mostly similar to the `workerData` 736 but the values will be available on the global `process.argv` as if they 737 were passed as CLI options to the script. 738 * `env` {Object} If set, specifies the initial value of `process.env` inside 739 the Worker thread. As a special value, [`worker.SHARE_ENV`][] may be used 740 to specify that the parent thread and the child thread should share their 741 environment variables; in that case, changes to one thread’s `process.env` 742 object will affect the other thread as well. **Default:** `process.env`. 743 * `eval` {boolean} If `true` and the first argument is a `string`, interpret 744 the first argument to the constructor as a script that is executed once the 745 worker is online. 746 * `execArgv` {string[]} List of node CLI options passed to the worker. 747 V8 options (such as `--max-old-space-size`) and options that affect the 748 process (such as `--title`) are not supported. If set, this will be provided 749 as [`process.execArgv`][] inside the worker. By default, options will be 750 inherited from the parent thread. 751 * `stdin` {boolean} If this is set to `true`, then `worker.stdin` will 752 provide a writable stream whose contents will appear as `process.stdin` 753 inside the Worker. By default, no data is provided. 754 * `stdout` {boolean} If this is set to `true`, then `worker.stdout` will 755 not automatically be piped through to `process.stdout` in the parent. 756 * `stderr` {boolean} If this is set to `true`, then `worker.stderr` will 757 not automatically be piped through to `process.stderr` in the parent. 758 * `workerData` {any} Any JavaScript value that will be cloned and made 759 available as [`require('worker_threads').workerData`][]. The cloning will 760 occur as described in the [HTML structured clone algorithm][], and an error 761 will be thrown if the object cannot be cloned (e.g. because it contains 762 `function`s). 763 * `trackUnmanagedFds` {boolean} If this is set to `true`, then the Worker will 764 track raw file descriptors managed through [`fs.open()`][] and 765 [`fs.close()`][], and close them when the Worker exits, similar to other 766 resources like network sockets or file descriptors managed through 767 the [`FileHandle`][] API. This option is automatically inherited by all 768 nested `Worker`s. **Default**: `false`. 769 * `transferList` {Object[]} If one or more `MessagePort`-like objects 770 are passed in `workerData`, a `transferList` is required for those 771 items or [`ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST`][] will be thrown. 772 See [`port.postMessage()`][] for more information. 773 * `resourceLimits` {Object} An optional set of resource limits for the new 774 JS engine instance. Reaching these limits will lead to termination of the 775 `Worker` instance. These limits only affect the JS engine, and no external 776 data, including no `ArrayBuffer`s. Even if these limits are set, the process 777 may still abort if it encounters a global out-of-memory situation. 778 * `maxOldGenerationSizeMb` {number} The maximum size of the main heap in MB. 779 * `maxYoungGenerationSizeMb` {number} The maximum size of a heap space for 780 recently created objects. 781 * `codeRangeSizeMb` {number} The size of a pre-allocated memory range 782 used for generated code. 783 * `stackSizeMb` {number} The default maximum stack size for the thread. 784 Small values may lead to unusable Worker instances. **Default:** `4`. 785 786### Event: `'error'` 787<!-- YAML 788added: v10.5.0 789--> 790 791* `err` {Error} 792 793The `'error'` event is emitted if the worker thread throws an uncaught 794exception. In that case, the worker will be terminated. 795 796### Event: `'exit'` 797<!-- YAML 798added: v10.5.0 799--> 800 801* `exitCode` {integer} 802 803The `'exit'` event is emitted once the worker has stopped. If the worker 804exited by calling [`process.exit()`][], the `exitCode` parameter will be the 805passed exit code. If the worker was terminated, the `exitCode` parameter will 806be `1`. 807 808This is the final event emitted by any `Worker` instance. 809 810### Event: `'message'` 811<!-- YAML 812added: v10.5.0 813--> 814 815* `value` {any} The transmitted value 816 817The `'message'` event is emitted when the worker thread has invoked 818[`require('worker_threads').parentPort.postMessage()`][]. 819See the [`port.on('message')`][] event for more details. 820 821All messages sent from the worker thread will be emitted before the 822[`'exit'` event][] is emitted on the `Worker` object. 823 824### Event: `'messageerror'` 825<!-- YAML 826added: v14.5.0 827--> 828 829* `error` {Error} An Error object 830 831The `'messageerror'` event is emitted when deserializing a message failed. 832 833### Event: `'online'` 834<!-- YAML 835added: v10.5.0 836--> 837 838The `'online'` event is emitted when the worker thread has started executing 839JavaScript code. 840 841### `worker.getHeapSnapshot()` 842<!-- YAML 843added: v13.9.0 844--> 845 846* Returns: {Promise} A promise for a Readable Stream containing 847 a V8 heap snapshot 848 849Returns a readable stream for a V8 snapshot of the current state of the Worker. 850See [`v8.getHeapSnapshot()`][] for more details. 851 852If the Worker thread is no longer running, which may occur before the 853[`'exit'` event][] is emitted, the returned `Promise` will be rejected 854immediately with an [`ERR_WORKER_NOT_RUNNING`][] error. 855 856### `worker.performance` 857<!-- YAML 858added: v14.17.0 859--> 860 861An object that can be used to query performance information from a worker 862instance. Similar to [`perf_hooks.performance`][]. 863 864#### `performance.eventLoopUtilization([utilization1[, utilization2]])` 865<!-- YAML 866added: v14.17.0 867--> 868 869* `utilization1` {Object} The result of a previous call to 870 `eventLoopUtilization()`. 871* `utilization2` {Object} The result of a previous call to 872 `eventLoopUtilization()` prior to `utilization1`. 873* Returns {Object} 874 * `idle` {number} 875 * `active` {number} 876 * `utilization` {number} 877 878The same call as [`perf_hooks` `eventLoopUtilization()`][], except the values 879of the worker instance are returned. 880 881One difference is that, unlike the main thread, bootstrapping within a worker 882is done within the event loop. So the event loop utilization will be 883immediately available once the worker's script begins execution. 884 885An `idle` time that does not increase does not indicate that the worker is 886stuck in bootstrap. The following examples shows how the worker's entire 887lifetime will never accumulate any `idle` time, but is still be able to process 888messages. 889 890```js 891const { Worker, isMainThread, parentPort } = require('worker_threads'); 892 893if (isMainThread) { 894 const worker = new Worker(__filename); 895 setInterval(() => { 896 worker.postMessage('hi'); 897 console.log(worker.performance.eventLoopUtilization()); 898 }, 100).unref(); 899 return; 900} 901 902parentPort.on('message', () => console.log('msg')).unref(); 903(function r(n) { 904 if (--n < 0) return; 905 const t = Date.now(); 906 while (Date.now() - t < 300); 907 setImmediate(r, n); 908})(10); 909``` 910 911The event loop utilization of a worker is available only after the [`'online'` 912event][] emitted, and if called before this, or after the [`'exit'` 913event][], then all properties have the value of `0`. 914 915### `worker.postMessage(value[, transferList])` 916<!-- YAML 917added: v10.5.0 918--> 919 920* `value` {any} 921* `transferList` {Object[]} 922 923Send a message to the worker that will be received via 924[`require('worker_threads').parentPort.on('message')`][]. 925See [`port.postMessage()`][] for more details. 926 927### `worker.ref()` 928<!-- YAML 929added: v10.5.0 930--> 931 932Opposite of `unref()`, calling `ref()` on a previously `unref()`ed worker will 933*not* let the program exit if it's the only active handle left (the default 934behavior). If the worker is `ref()`ed, calling `ref()` again will have 935no effect. 936 937### `worker.resourceLimits` 938<!-- YAML 939added: 940 - v13.2.0 941 - v12.16.0 942--> 943 944* {Object} 945 * `maxYoungGenerationSizeMb` {number} 946 * `maxOldGenerationSizeMb` {number} 947 * `codeRangeSizeMb` {number} 948 * `stackSizeMb` {number} 949 950Provides the set of JS engine resource constraints for this Worker thread. 951If the `resourceLimits` option was passed to the [`Worker`][] constructor, 952this matches its values. 953 954If the worker has stopped, the return value is an empty object. 955 956### `worker.stderr` 957<!-- YAML 958added: v10.5.0 959--> 960 961* {stream.Readable} 962 963This is a readable stream which contains data written to [`process.stderr`][] 964inside the worker thread. If `stderr: true` was not passed to the 965[`Worker`][] constructor, then data will be piped to the parent thread's 966[`process.stderr`][] stream. 967 968### `worker.stdin` 969<!-- YAML 970added: v10.5.0 971--> 972 973* {null|stream.Writable} 974 975If `stdin: true` was passed to the [`Worker`][] constructor, this is a 976writable stream. The data written to this stream will be made available in 977the worker thread as [`process.stdin`][]. 978 979### `worker.stdout` 980<!-- YAML 981added: v10.5.0 982--> 983 984* {stream.Readable} 985 986This is a readable stream which contains data written to [`process.stdout`][] 987inside the worker thread. If `stdout: true` was not passed to the 988[`Worker`][] constructor, then data will be piped to the parent thread's 989[`process.stdout`][] stream. 990 991### `worker.terminate()` 992<!-- YAML 993added: v10.5.0 994changes: 995 - version: v12.5.0 996 pr-url: https://github.com/nodejs/node/pull/28021 997 description: This function now returns a Promise. 998 Passing a callback is deprecated, and was useless up to this 999 version, as the Worker was actually terminated synchronously. 1000 Terminating is now a fully asynchronous operation. 1001--> 1002 1003* Returns: {Promise} 1004 1005Stop all JavaScript execution in the worker thread as soon as possible. 1006Returns a Promise for the exit code that is fulfilled when the 1007[`'exit'` event][] is emitted. 1008 1009### `worker.threadId` 1010<!-- YAML 1011added: v10.5.0 1012--> 1013 1014* {integer} 1015 1016An integer identifier for the referenced thread. Inside the worker thread, 1017it is available as [`require('worker_threads').threadId`][]. 1018This value is unique for each `Worker` instance inside a single process. 1019 1020### `worker.unref()` 1021<!-- YAML 1022added: v10.5.0 1023--> 1024 1025Calling `unref()` on a worker will allow the thread to exit if this is the only 1026active handle in the event system. If the worker is already `unref()`ed calling 1027`unref()` again will have no effect. 1028 1029## Notes 1030 1031### Synchronous blocking of stdio 1032 1033`Worker`s utilize message passing via {MessagePort} to implement interactions 1034with `stdio`. This means that `stdio` output originating from a `Worker` can 1035get blocked by synchronous code on the receiving end that is blocking the 1036Node.js event loop. 1037 1038```mjs 1039import { 1040 Worker, 1041 isMainThread, 1042} from 'worker_threads'; 1043 1044if (isMainThread) { 1045 new Worker(new URL(import.meta.url)); 1046 for (let n = 0; n < 1e10; n++) {} 1047} else { 1048 // This output will be blocked by the for loop in the main thread. 1049 console.log('foo'); 1050} 1051``` 1052 1053```cjs 1054'use strict'; 1055 1056const { 1057 Worker, 1058 isMainThread, 1059} = require('worker_threads'); 1060 1061if (isMainThread) { 1062 new Worker(__filename); 1063 for (let n = 0; n < 1e10; n++) {} 1064} else { 1065 // This output will be blocked by the for loop in the main thread. 1066 console.log('foo'); 1067} 1068``` 1069 1070### Launching worker threads from preload scripts 1071 1072Take care when launching worker threads from preload scripts (scripts loaded 1073and run using the `-r` command line flag). Unless the `execArgv` option is 1074explicitly set, new Worker threads automatically inherit the command line flags 1075from the running process and will preload the same preload scripts as the main 1076thread. If the preload script unconditionally launches a worker thread, every 1077thread spawned will spawn another until the application crashes. 1078 1079[Addons worker support]: addons.md#addons_worker_support 1080[ECMAScript module loader]: esm.md#esm_data_imports 1081[HTML structured clone algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm 1082[Signals events]: process.md#process_signal_events 1083[Web Workers]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API 1084[`'close'` event]: #worker_threads_event_close 1085[`'exit'` event]: #worker_threads_event_exit 1086[`'online'` event]: #worker_threads_event_online 1087[`ArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer 1088[`AsyncResource`]: async_hooks.md#async_hooks_class_asyncresource 1089[`Buffer.allocUnsafe()`]: buffer.md#buffer_static_method_buffer_allocunsafe_size 1090[`Buffer`]: buffer.md 1091[`ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST`]: errors.md#errors_err_missing_message_port_in_transfer_list 1092[`ERR_WORKER_NOT_RUNNING`]: errors.md#ERR_WORKER_NOT_RUNNING 1093[`EventTarget`]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget 1094[`FileHandle`]: fs.md#fs_class_filehandle 1095[`MessagePort`]: #worker_threads_class_messageport 1096[`SharedArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer 1097[`Uint8Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array 1098[`WebAssembly.Module`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module 1099[`Worker constructor options`]: #worker_threads_new_worker_filename_options 1100[`Worker`]: #worker_threads_class_worker 1101[`cluster` module]: cluster.md 1102[`data:` URL]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs 1103[`fs.close()`]: fs.md#fs_fs_close_fd_callback 1104[`fs.open()`]: fs.md#fs_fs_open_path_flags_mode_callback 1105[`markAsUntransferable()`]: #worker_threads_worker_markasuntransferable_object 1106[`perf_hooks.performance`]: perf_hooks.md#perf_hooks_perf_hooks_performance 1107[`perf_hooks` `eventLoopUtilization()`]: perf_hooks.md#perf_hooks_performance_eventlooputilization_utilization1_utilization2 1108[`port.on('message')`]: #worker_threads_event_message 1109[`port.onmessage()`]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort/onmessage 1110[`port.postMessage()`]: #worker_threads_port_postmessage_value_transferlist 1111[`process.abort()`]: process.md#process_process_abort 1112[`process.chdir()`]: process.md#process_process_chdir_directory 1113[`process.env`]: process.md#process_process_env 1114[`process.execArgv`]: process.md#process_process_execargv 1115[`process.exit()`]: process.md#process_process_exit_code 1116[`process.stderr`]: process.md#process_process_stderr 1117[`process.stdin`]: process.md#process_process_stdin 1118[`process.stdout`]: process.md#process_process_stdout 1119[`process.title`]: process.md#process_process_title 1120[`require('worker_threads').isMainThread`]: #worker_threads_worker_ismainthread 1121[`require('worker_threads').parentPort.on('message')`]: #worker_threads_event_message 1122[`require('worker_threads').parentPort.postMessage()`]: #worker_threads_worker_postmessage_value_transferlist 1123[`require('worker_threads').parentPort`]: #worker_threads_worker_parentport 1124[`require('worker_threads').threadId`]: #worker_threads_worker_threadid 1125[`require('worker_threads').workerData`]: #worker_threads_worker_workerdata 1126[`trace_events`]: tracing.md 1127[`v8.getHeapSnapshot()`]: v8.md#v8_v8_getheapsnapshot 1128[`vm`]: vm.md 1129[`worker.SHARE_ENV`]: #worker_threads_worker_share_env 1130[`worker.on('message')`]: #worker_threads_event_message_1 1131[`worker.postMessage()`]: #worker_threads_worker_postmessage_value_transferlist 1132[`worker.terminate()`]: #worker_threads_worker_terminate 1133[`worker.threadId`]: #worker_threads_worker_threadid_1 1134[async-resource-worker-pool]: async_hooks.md#async-resource-worker-pool 1135[browser `MessagePort`]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort 1136[child processes]: child_process.md 1137[contextified]: vm.md#vm_what_does_it_mean_to_contextify_an_object 1138[v8.serdes]: v8.md#v8_serialization_api 1139