1# Cluster 2 3<!--introduced_in=v0.10.0--> 4 5> Stability: 2 - Stable 6 7<!-- source_link=lib/cluster.js --> 8 9Clusters of Node.js processes can be used to run multiple instances of Node.js 10that can distribute workloads among their application threads. When process 11isolation is not needed, use the [`worker_threads`][] module instead, which 12allows running multiple application threads within a single Node.js instance. 13 14The cluster module allows easy creation of child processes that all share 15server ports. 16 17```mjs 18import cluster from 'node:cluster'; 19import http from 'node:http'; 20import { availableParallelism } from 'node:os'; 21import process from 'node:process'; 22 23const numCPUs = availableParallelism(); 24 25if (cluster.isPrimary) { 26 console.log(`Primary ${process.pid} is running`); 27 28 // Fork workers. 29 for (let i = 0; i < numCPUs; i++) { 30 cluster.fork(); 31 } 32 33 cluster.on('exit', (worker, code, signal) => { 34 console.log(`worker ${worker.process.pid} died`); 35 }); 36} else { 37 // Workers can share any TCP connection 38 // In this case it is an HTTP server 39 http.createServer((req, res) => { 40 res.writeHead(200); 41 res.end('hello world\n'); 42 }).listen(8000); 43 44 console.log(`Worker ${process.pid} started`); 45} 46``` 47 48```cjs 49const cluster = require('node:cluster'); 50const http = require('node:http'); 51const numCPUs = require('node:os').availableParallelism(); 52const process = require('node:process'); 53 54if (cluster.isPrimary) { 55 console.log(`Primary ${process.pid} is running`); 56 57 // Fork workers. 58 for (let i = 0; i < numCPUs; i++) { 59 cluster.fork(); 60 } 61 62 cluster.on('exit', (worker, code, signal) => { 63 console.log(`worker ${worker.process.pid} died`); 64 }); 65} else { 66 // Workers can share any TCP connection 67 // In this case it is an HTTP server 68 http.createServer((req, res) => { 69 res.writeHead(200); 70 res.end('hello world\n'); 71 }).listen(8000); 72 73 console.log(`Worker ${process.pid} started`); 74} 75``` 76 77Running Node.js will now share port 8000 between the workers: 78 79```console 80$ node server.js 81Primary 3596 is running 82Worker 4324 started 83Worker 4520 started 84Worker 6056 started 85Worker 5644 started 86``` 87 88On Windows, it is not yet possible to set up a named pipe server in a worker. 89 90## How it works 91 92<!--type=misc--> 93 94The worker processes are spawned using the [`child_process.fork()`][] method, 95so that they can communicate with the parent via IPC and pass server 96handles back and forth. 97 98The cluster module supports two methods of distributing incoming 99connections. 100 101The first one (and the default one on all platforms except Windows) 102is the round-robin approach, where the primary process listens on a 103port, accepts new connections and distributes them across the workers 104in a round-robin fashion, with some built-in smarts to avoid 105overloading a worker process. 106 107The second approach is where the primary process creates the listen 108socket and sends it to interested workers. The workers then accept 109incoming connections directly. 110 111The second approach should, in theory, give the best performance. 112In practice however, distribution tends to be very unbalanced due 113to operating system scheduler vagaries. Loads have been observed 114where over 70% of all connections ended up in just two processes, 115out of a total of eight. 116 117Because `server.listen()` hands off most of the work to the primary 118process, there are three cases where the behavior between a normal 119Node.js process and a cluster worker differs: 120 1211. `server.listen({fd: 7})` Because the message is passed to the primary, 122 file descriptor 7 **in the parent** will be listened on, and the 123 handle passed to the worker, rather than listening to the worker's 124 idea of what the number 7 file descriptor references. 1252. `server.listen(handle)` Listening on handles explicitly will cause 126 the worker to use the supplied handle, rather than talk to the primary 127 process. 1283. `server.listen(0)` Normally, this will cause servers to listen on a 129 random port. However, in a cluster, each worker will receive the 130 same "random" port each time they do `listen(0)`. In essence, the 131 port is random the first time, but predictable thereafter. To listen 132 on a unique port, generate a port number based on the cluster worker ID. 133 134Node.js does not provide routing logic. It is therefore important to design an 135application such that it does not rely too heavily on in-memory data objects for 136things like sessions and login. 137 138Because workers are all separate processes, they can be killed or 139re-spawned depending on a program's needs, without affecting other 140workers. As long as there are some workers still alive, the server will 141continue to accept connections. If no workers are alive, existing connections 142will be dropped and new connections will be refused. Node.js does not 143automatically manage the number of workers, however. It is the application's 144responsibility to manage the worker pool based on its own needs. 145 146Although a primary use case for the `node:cluster` module is networking, it can 147also be used for other use cases requiring worker processes. 148 149## Class: `Worker` 150 151<!-- YAML 152added: v0.7.0 153--> 154 155* Extends: {EventEmitter} 156 157A `Worker` object contains all public information and method about a worker. 158In the primary it can be obtained using `cluster.workers`. In a worker 159it can be obtained using `cluster.worker`. 160 161### Event: `'disconnect'` 162 163<!-- YAML 164added: v0.7.7 165--> 166 167Similar to the `cluster.on('disconnect')` event, but specific to this worker. 168 169```js 170cluster.fork().on('disconnect', () => { 171 // Worker has disconnected 172}); 173``` 174 175### Event: `'error'` 176 177<!-- YAML 178added: v0.7.3 179--> 180 181This event is the same as the one provided by [`child_process.fork()`][]. 182 183Within a worker, `process.on('error')` may also be used. 184 185### Event: `'exit'` 186 187<!-- YAML 188added: v0.11.2 189--> 190 191* `code` {number} The exit code, if it exited normally. 192* `signal` {string} The name of the signal (e.g. `'SIGHUP'`) that caused 193 the process to be killed. 194 195Similar to the `cluster.on('exit')` event, but specific to this worker. 196 197```mjs 198import cluster from 'node:cluster'; 199 200if (cluster.isPrimary) { 201 const worker = cluster.fork(); 202 worker.on('exit', (code, signal) => { 203 if (signal) { 204 console.log(`worker was killed by signal: ${signal}`); 205 } else if (code !== 0) { 206 console.log(`worker exited with error code: ${code}`); 207 } else { 208 console.log('worker success!'); 209 } 210 }); 211} 212``` 213 214```cjs 215const cluster = require('node:cluster'); 216 217if (cluster.isPrimary) { 218 const worker = cluster.fork(); 219 worker.on('exit', (code, signal) => { 220 if (signal) { 221 console.log(`worker was killed by signal: ${signal}`); 222 } else if (code !== 0) { 223 console.log(`worker exited with error code: ${code}`); 224 } else { 225 console.log('worker success!'); 226 } 227 }); 228} 229``` 230 231### Event: `'listening'` 232 233<!-- YAML 234added: v0.7.0 235--> 236 237* `address` {Object} 238 239Similar to the `cluster.on('listening')` event, but specific to this worker. 240 241```mjs 242cluster.fork().on('listening', (address) => { 243 // Worker is listening 244}); 245``` 246 247```cjs 248cluster.fork().on('listening', (address) => { 249 // Worker is listening 250}); 251``` 252 253It is not emitted in the worker. 254 255### Event: `'message'` 256 257<!-- YAML 258added: v0.7.0 259--> 260 261* `message` {Object} 262* `handle` {undefined|Object} 263 264Similar to the `'message'` event of `cluster`, but specific to this worker. 265 266Within a worker, `process.on('message')` may also be used. 267 268See [`process` event: `'message'`][]. 269 270Here is an example using the message system. It keeps a count in the primary 271process of the number of HTTP requests received by the workers: 272 273```mjs 274import cluster from 'node:cluster'; 275import http from 'node:http'; 276import { availableParallelism } from 'node:os'; 277import process from 'node:process'; 278 279if (cluster.isPrimary) { 280 281 // Keep track of http requests 282 let numReqs = 0; 283 setInterval(() => { 284 console.log(`numReqs = ${numReqs}`); 285 }, 1000); 286 287 // Count requests 288 function messageHandler(msg) { 289 if (msg.cmd && msg.cmd === 'notifyRequest') { 290 numReqs += 1; 291 } 292 } 293 294 // Start workers and listen for messages containing notifyRequest 295 const numCPUs = availableParallelism(); 296 for (let i = 0; i < numCPUs; i++) { 297 cluster.fork(); 298 } 299 300 for (const id in cluster.workers) { 301 cluster.workers[id].on('message', messageHandler); 302 } 303 304} else { 305 306 // Worker processes have a http server. 307 http.Server((req, res) => { 308 res.writeHead(200); 309 res.end('hello world\n'); 310 311 // Notify primary about the request 312 process.send({ cmd: 'notifyRequest' }); 313 }).listen(8000); 314} 315``` 316 317```cjs 318const cluster = require('node:cluster'); 319const http = require('node:http'); 320const process = require('node:process'); 321 322if (cluster.isPrimary) { 323 324 // Keep track of http requests 325 let numReqs = 0; 326 setInterval(() => { 327 console.log(`numReqs = ${numReqs}`); 328 }, 1000); 329 330 // Count requests 331 function messageHandler(msg) { 332 if (msg.cmd && msg.cmd === 'notifyRequest') { 333 numReqs += 1; 334 } 335 } 336 337 // Start workers and listen for messages containing notifyRequest 338 const numCPUs = require('node:os').availableParallelism(); 339 for (let i = 0; i < numCPUs; i++) { 340 cluster.fork(); 341 } 342 343 for (const id in cluster.workers) { 344 cluster.workers[id].on('message', messageHandler); 345 } 346 347} else { 348 349 // Worker processes have a http server. 350 http.Server((req, res) => { 351 res.writeHead(200); 352 res.end('hello world\n'); 353 354 // Notify primary about the request 355 process.send({ cmd: 'notifyRequest' }); 356 }).listen(8000); 357} 358``` 359 360### Event: `'online'` 361 362<!-- YAML 363added: v0.7.0 364--> 365 366Similar to the `cluster.on('online')` event, but specific to this worker. 367 368```js 369cluster.fork().on('online', () => { 370 // Worker is online 371}); 372``` 373 374It is not emitted in the worker. 375 376### `worker.disconnect()` 377 378<!-- YAML 379added: v0.7.7 380changes: 381 - version: v7.3.0 382 pr-url: https://github.com/nodejs/node/pull/10019 383 description: This method now returns a reference to `worker`. 384--> 385 386* Returns: {cluster.Worker} A reference to `worker`. 387 388In a worker, this function will close all servers, wait for the `'close'` event 389on those servers, and then disconnect the IPC channel. 390 391In the primary, an internal message is sent to the worker causing it to call 392`.disconnect()` on itself. 393 394Causes `.exitedAfterDisconnect` to be set. 395 396After a server is closed, it will no longer accept new connections, 397but connections may be accepted by any other listening worker. Existing 398connections will be allowed to close as usual. When no more connections exist, 399see [`server.close()`][], the IPC channel to the worker will close allowing it 400to die gracefully. 401 402The above applies _only_ to server connections, client connections are not 403automatically closed by workers, and disconnect does not wait for them to close 404before exiting. 405 406In a worker, `process.disconnect` exists, but it is not this function; 407it is [`disconnect()`][]. 408 409Because long living server connections may block workers from disconnecting, it 410may be useful to send a message, so application specific actions may be taken to 411close them. It also may be useful to implement a timeout, killing a worker if 412the `'disconnect'` event has not been emitted after some time. 413 414```js 415if (cluster.isPrimary) { 416 const worker = cluster.fork(); 417 let timeout; 418 419 worker.on('listening', (address) => { 420 worker.send('shutdown'); 421 worker.disconnect(); 422 timeout = setTimeout(() => { 423 worker.kill(); 424 }, 2000); 425 }); 426 427 worker.on('disconnect', () => { 428 clearTimeout(timeout); 429 }); 430 431} else if (cluster.isWorker) { 432 const net = require('node:net'); 433 const server = net.createServer((socket) => { 434 // Connections never end 435 }); 436 437 server.listen(8000); 438 439 process.on('message', (msg) => { 440 if (msg === 'shutdown') { 441 // Initiate graceful close of any connections to server 442 } 443 }); 444} 445``` 446 447### `worker.exitedAfterDisconnect` 448 449<!-- YAML 450added: v6.0.0 451--> 452 453* {boolean} 454 455This property is `true` if the worker exited due to `.disconnect()`. 456If the worker exited any other way, it is `false`. If the 457worker has not exited, it is `undefined`. 458 459The boolean [`worker.exitedAfterDisconnect`][] allows distinguishing between 460voluntary and accidental exit, the primary may choose not to respawn a worker 461based on this value. 462 463```js 464cluster.on('exit', (worker, code, signal) => { 465 if (worker.exitedAfterDisconnect === true) { 466 console.log('Oh, it was just voluntary – no need to worry'); 467 } 468}); 469 470// kill worker 471worker.kill(); 472``` 473 474### `worker.id` 475 476<!-- YAML 477added: v0.8.0 478--> 479 480* {integer} 481 482Each new worker is given its own unique id, this id is stored in the 483`id`. 484 485While a worker is alive, this is the key that indexes it in 486`cluster.workers`. 487 488### `worker.isConnected()` 489 490<!-- YAML 491added: v0.11.14 492--> 493 494This function returns `true` if the worker is connected to its primary via its 495IPC channel, `false` otherwise. A worker is connected to its primary after it 496has been created. It is disconnected after the `'disconnect'` event is emitted. 497 498### `worker.isDead()` 499 500<!-- YAML 501added: v0.11.14 502--> 503 504This function returns `true` if the worker's process has terminated (either 505because of exiting or being signaled). Otherwise, it returns `false`. 506 507```mjs 508import cluster from 'node:cluster'; 509import http from 'node:http'; 510import { availableParallelism } from 'node:os'; 511import process from 'node:process'; 512 513const numCPUs = availableParallelism(); 514 515if (cluster.isPrimary) { 516 console.log(`Primary ${process.pid} is running`); 517 518 // Fork workers. 519 for (let i = 0; i < numCPUs; i++) { 520 cluster.fork(); 521 } 522 523 cluster.on('fork', (worker) => { 524 console.log('worker is dead:', worker.isDead()); 525 }); 526 527 cluster.on('exit', (worker, code, signal) => { 528 console.log('worker is dead:', worker.isDead()); 529 }); 530} else { 531 // Workers can share any TCP connection. In this case, it is an HTTP server. 532 http.createServer((req, res) => { 533 res.writeHead(200); 534 res.end(`Current process\n ${process.pid}`); 535 process.kill(process.pid); 536 }).listen(8000); 537} 538``` 539 540```cjs 541const cluster = require('node:cluster'); 542const http = require('node:http'); 543const numCPUs = require('node:os').availableParallelism(); 544const process = require('node:process'); 545 546if (cluster.isPrimary) { 547 console.log(`Primary ${process.pid} is running`); 548 549 // Fork workers. 550 for (let i = 0; i < numCPUs; i++) { 551 cluster.fork(); 552 } 553 554 cluster.on('fork', (worker) => { 555 console.log('worker is dead:', worker.isDead()); 556 }); 557 558 cluster.on('exit', (worker, code, signal) => { 559 console.log('worker is dead:', worker.isDead()); 560 }); 561} else { 562 // Workers can share any TCP connection. In this case, it is an HTTP server. 563 http.createServer((req, res) => { 564 res.writeHead(200); 565 res.end(`Current process\n ${process.pid}`); 566 process.kill(process.pid); 567 }).listen(8000); 568} 569``` 570 571### `worker.kill([signal])` 572 573<!-- YAML 574added: v0.9.12 575--> 576 577* `signal` {string} Name of the kill signal to send to the worker 578 process. **Default:** `'SIGTERM'` 579 580This function will kill the worker. In the primary worker, it does this by 581disconnecting the `worker.process`, and once disconnected, killing with 582`signal`. In the worker, it does it by killing the process with `signal`. 583 584The `kill()` function kills the worker process without waiting for a graceful 585disconnect, it has the same behavior as `worker.process.kill()`. 586 587This method is aliased as `worker.destroy()` for backwards compatibility. 588 589In a worker, `process.kill()` exists, but it is not this function; 590it is [`kill()`][]. 591 592### `worker.process` 593 594<!-- YAML 595added: v0.7.0 596--> 597 598* {ChildProcess} 599 600All workers are created using [`child_process.fork()`][], the returned object 601from this function is stored as `.process`. In a worker, the global `process` 602is stored. 603 604See: [Child Process module][]. 605 606Workers will call `process.exit(0)` if the `'disconnect'` event occurs 607on `process` and `.exitedAfterDisconnect` is not `true`. This protects against 608accidental disconnection. 609 610### `worker.send(message[, sendHandle[, options]][, callback])` 611 612<!-- YAML 613added: v0.7.0 614changes: 615 - version: v4.0.0 616 pr-url: https://github.com/nodejs/node/pull/2620 617 description: The `callback` parameter is supported now. 618--> 619 620* `message` {Object} 621* `sendHandle` {Handle} 622* `options` {Object} The `options` argument, if present, is an object used to 623 parameterize the sending of certain types of handles. `options` supports 624 the following properties: 625 * `keepOpen` {boolean} A value that can be used when passing instances of 626 `net.Socket`. When `true`, the socket is kept open in the sending process. 627 **Default:** `false`. 628* `callback` {Function} 629* Returns: {boolean} 630 631Send a message to a worker or primary, optionally with a handle. 632 633In the primary, this sends a message to a specific worker. It is identical to 634[`ChildProcess.send()`][]. 635 636In a worker, this sends a message to the primary. It is identical to 637`process.send()`. 638 639This example will echo back all messages from the primary: 640 641```js 642if (cluster.isPrimary) { 643 const worker = cluster.fork(); 644 worker.send('hi there'); 645 646} else if (cluster.isWorker) { 647 process.on('message', (msg) => { 648 process.send(msg); 649 }); 650} 651``` 652 653## Event: `'disconnect'` 654 655<!-- YAML 656added: v0.7.9 657--> 658 659* `worker` {cluster.Worker} 660 661Emitted after the worker IPC channel has disconnected. This can occur when a 662worker exits gracefully, is killed, or is disconnected manually (such as with 663`worker.disconnect()`). 664 665There may be a delay between the `'disconnect'` and `'exit'` events. These 666events can be used to detect if the process is stuck in a cleanup or if there 667are long-living connections. 668 669```js 670cluster.on('disconnect', (worker) => { 671 console.log(`The worker #${worker.id} has disconnected`); 672}); 673``` 674 675## Event: `'exit'` 676 677<!-- YAML 678added: v0.7.9 679--> 680 681* `worker` {cluster.Worker} 682* `code` {number} The exit code, if it exited normally. 683* `signal` {string} The name of the signal (e.g. `'SIGHUP'`) that caused 684 the process to be killed. 685 686When any of the workers die the cluster module will emit the `'exit'` event. 687 688This can be used to restart the worker by calling [`.fork()`][] again. 689 690```js 691cluster.on('exit', (worker, code, signal) => { 692 console.log('worker %d died (%s). restarting...', 693 worker.process.pid, signal || code); 694 cluster.fork(); 695}); 696``` 697 698See [`child_process` event: `'exit'`][]. 699 700## Event: `'fork'` 701 702<!-- YAML 703added: v0.7.0 704--> 705 706* `worker` {cluster.Worker} 707 708When a new worker is forked the cluster module will emit a `'fork'` event. 709This can be used to log worker activity, and create a custom timeout. 710 711```js 712const timeouts = []; 713function errorMsg() { 714 console.error('Something must be wrong with the connection ...'); 715} 716 717cluster.on('fork', (worker) => { 718 timeouts[worker.id] = setTimeout(errorMsg, 2000); 719}); 720cluster.on('listening', (worker, address) => { 721 clearTimeout(timeouts[worker.id]); 722}); 723cluster.on('exit', (worker, code, signal) => { 724 clearTimeout(timeouts[worker.id]); 725 errorMsg(); 726}); 727``` 728 729## Event: `'listening'` 730 731<!-- YAML 732added: v0.7.0 733--> 734 735* `worker` {cluster.Worker} 736* `address` {Object} 737 738After calling `listen()` from a worker, when the `'listening'` event is emitted 739on the server, a `'listening'` event will also be emitted on `cluster` in the 740primary. 741 742The event handler is executed with two arguments, the `worker` contains the 743worker object and the `address` object contains the following connection 744properties: `address`, `port`, and `addressType`. This is very useful if the 745worker is listening on more than one address. 746 747```js 748cluster.on('listening', (worker, address) => { 749 console.log( 750 `A worker is now connected to ${address.address}:${address.port}`); 751}); 752``` 753 754The `addressType` is one of: 755 756* `4` (TCPv4) 757* `6` (TCPv6) 758* `-1` (Unix domain socket) 759* `'udp4'` or `'udp6'` (UDPv4 or UDPv6) 760 761## Event: `'message'` 762 763<!-- YAML 764added: v2.5.0 765changes: 766 - version: v6.0.0 767 pr-url: https://github.com/nodejs/node/pull/5361 768 description: The `worker` parameter is passed now; see below for details. 769--> 770 771* `worker` {cluster.Worker} 772* `message` {Object} 773* `handle` {undefined|Object} 774 775Emitted when the cluster primary receives a message from any worker. 776 777See [`child_process` event: `'message'`][]. 778 779## Event: `'online'` 780 781<!-- YAML 782added: v0.7.0 783--> 784 785* `worker` {cluster.Worker} 786 787After forking a new worker, the worker should respond with an online message. 788When the primary receives an online message it will emit this event. 789The difference between `'fork'` and `'online'` is that fork is emitted when the 790primary forks a worker, and `'online'` is emitted when the worker is running. 791 792```js 793cluster.on('online', (worker) => { 794 console.log('Yay, the worker responded after it was forked'); 795}); 796``` 797 798## Event: `'setup'` 799 800<!-- YAML 801added: v0.7.1 802--> 803 804* `settings` {Object} 805 806Emitted every time [`.setupPrimary()`][] is called. 807 808The `settings` object is the `cluster.settings` object at the time 809[`.setupPrimary()`][] was called and is advisory only, since multiple calls to 810[`.setupPrimary()`][] can be made in a single tick. 811 812If accuracy is important, use `cluster.settings`. 813 814## `cluster.disconnect([callback])` 815 816<!-- YAML 817added: v0.7.7 818--> 819 820* `callback` {Function} Called when all workers are disconnected and handles are 821 closed. 822 823Calls `.disconnect()` on each worker in `cluster.workers`. 824 825When they are disconnected all internal handles will be closed, allowing the 826primary process to die gracefully if no other event is waiting. 827 828The method takes an optional callback argument which will be called when 829finished. 830 831This can only be called from the primary process. 832 833## `cluster.fork([env])` 834 835<!-- YAML 836added: v0.6.0 837--> 838 839* `env` {Object} Key/value pairs to add to worker process environment. 840* Returns: {cluster.Worker} 841 842Spawn a new worker process. 843 844This can only be called from the primary process. 845 846## `cluster.isMaster` 847 848<!-- YAML 849added: v0.8.1 850deprecated: v16.0.0 851--> 852 853> Stability: 0 - Deprecated 854 855Deprecated alias for [`cluster.isPrimary`][]. 856 857## `cluster.isPrimary` 858 859<!-- YAML 860added: v16.0.0 861--> 862 863* {boolean} 864 865True if the process is a primary. This is determined 866by the `process.env.NODE_UNIQUE_ID`. If `process.env.NODE_UNIQUE_ID` is 867undefined, then `isPrimary` is `true`. 868 869## `cluster.isWorker` 870 871<!-- YAML 872added: v0.6.0 873--> 874 875* {boolean} 876 877True if the process is not a primary (it is the negation of `cluster.isPrimary`). 878 879## `cluster.schedulingPolicy` 880 881<!-- YAML 882added: v0.11.2 883--> 884 885The scheduling policy, either `cluster.SCHED_RR` for round-robin or 886`cluster.SCHED_NONE` to leave it to the operating system. This is a 887global setting and effectively frozen once either the first worker is spawned, 888or [`.setupPrimary()`][] is called, whichever comes first. 889 890`SCHED_RR` is the default on all operating systems except Windows. 891Windows will change to `SCHED_RR` once libuv is able to effectively 892distribute IOCP handles without incurring a large performance hit. 893 894`cluster.schedulingPolicy` can also be set through the 895`NODE_CLUSTER_SCHED_POLICY` environment variable. Valid 896values are `'rr'` and `'none'`. 897 898## `cluster.settings` 899 900<!-- YAML 901added: v0.7.1 902changes: 903 - version: 904 - v13.2.0 905 - v12.16.0 906 pr-url: https://github.com/nodejs/node/pull/30162 907 description: The `serialization` option is supported now. 908 - version: v9.5.0 909 pr-url: https://github.com/nodejs/node/pull/18399 910 description: The `cwd` option is supported now. 911 - version: v9.4.0 912 pr-url: https://github.com/nodejs/node/pull/17412 913 description: The `windowsHide` option is supported now. 914 - version: v8.2.0 915 pr-url: https://github.com/nodejs/node/pull/14140 916 description: The `inspectPort` option is supported now. 917 - version: v6.4.0 918 pr-url: https://github.com/nodejs/node/pull/7838 919 description: The `stdio` option is supported now. 920--> 921 922* {Object} 923 * `execArgv` {string\[]} List of string arguments passed to the Node.js 924 executable. **Default:** `process.execArgv`. 925 * `exec` {string} File path to worker file. **Default:** `process.argv[1]`. 926 * `args` {string\[]} String arguments passed to worker. 927 **Default:** `process.argv.slice(2)`. 928 * `cwd` {string} Current working directory of the worker process. **Default:** 929 `undefined` (inherits from parent process). 930 * `serialization` {string} Specify the kind of serialization used for sending 931 messages between processes. Possible values are `'json'` and `'advanced'`. 932 See [Advanced serialization for `child_process`][] for more details. 933 **Default:** `false`. 934 * `silent` {boolean} Whether or not to send output to parent's stdio. 935 **Default:** `false`. 936 * `stdio` {Array} Configures the stdio of forked processes. Because the 937 cluster module relies on IPC to function, this configuration must contain an 938 `'ipc'` entry. When this option is provided, it overrides `silent`. See 939 [`child_process.spawn()`][]'s [`stdio`][]. 940 * `uid` {number} Sets the user identity of the process. (See setuid(2).) 941 * `gid` {number} Sets the group identity of the process. (See setgid(2).) 942 * `inspectPort` {number|Function} Sets inspector port of worker. 943 This can be a number, or a function that takes no arguments and returns a 944 number. By default each worker gets its own port, incremented from the 945 primary's `process.debugPort`. 946 * `windowsHide` {boolean} Hide the forked processes console window that would 947 normally be created on Windows systems. **Default:** `false`. 948 949After calling [`.setupPrimary()`][] (or [`.fork()`][]) this settings object will 950contain the settings, including the default values. 951 952This object is not intended to be changed or set manually. 953 954## `cluster.setupMaster([settings])` 955 956<!-- YAML 957added: v0.7.1 958deprecated: v16.0.0 959changes: 960 - version: v6.4.0 961 pr-url: https://github.com/nodejs/node/pull/7838 962 description: The `stdio` option is supported now. 963--> 964 965> Stability: 0 - Deprecated 966 967Deprecated alias for [`.setupPrimary()`][]. 968 969## `cluster.setupPrimary([settings])` 970 971<!-- YAML 972added: v16.0.0 973--> 974 975* `settings` {Object} See [`cluster.settings`][]. 976 977`setupPrimary` is used to change the default 'fork' behavior. Once called, 978the settings will be present in `cluster.settings`. 979 980Any settings changes only affect future calls to [`.fork()`][] and have no 981effect on workers that are already running. 982 983The only attribute of a worker that cannot be set via `.setupPrimary()` is 984the `env` passed to [`.fork()`][]. 985 986The defaults above apply to the first call only; the defaults for later 987calls are the current values at the time of `cluster.setupPrimary()` is called. 988 989```mjs 990import cluster from 'node:cluster'; 991 992cluster.setupPrimary({ 993 exec: 'worker.js', 994 args: ['--use', 'https'], 995 silent: true, 996}); 997cluster.fork(); // https worker 998cluster.setupPrimary({ 999 exec: 'worker.js', 1000 args: ['--use', 'http'], 1001}); 1002cluster.fork(); // http worker 1003``` 1004 1005```cjs 1006const cluster = require('node:cluster'); 1007 1008cluster.setupPrimary({ 1009 exec: 'worker.js', 1010 args: ['--use', 'https'], 1011 silent: true, 1012}); 1013cluster.fork(); // https worker 1014cluster.setupPrimary({ 1015 exec: 'worker.js', 1016 args: ['--use', 'http'], 1017}); 1018cluster.fork(); // http worker 1019``` 1020 1021This can only be called from the primary process. 1022 1023## `cluster.worker` 1024 1025<!-- YAML 1026added: v0.7.0 1027--> 1028 1029* {Object} 1030 1031A reference to the current worker object. Not available in the primary process. 1032 1033```mjs 1034import cluster from 'node:cluster'; 1035 1036if (cluster.isPrimary) { 1037 console.log('I am primary'); 1038 cluster.fork(); 1039 cluster.fork(); 1040} else if (cluster.isWorker) { 1041 console.log(`I am worker #${cluster.worker.id}`); 1042} 1043``` 1044 1045```cjs 1046const cluster = require('node:cluster'); 1047 1048if (cluster.isPrimary) { 1049 console.log('I am primary'); 1050 cluster.fork(); 1051 cluster.fork(); 1052} else if (cluster.isWorker) { 1053 console.log(`I am worker #${cluster.worker.id}`); 1054} 1055``` 1056 1057## `cluster.workers` 1058 1059<!-- YAML 1060added: v0.7.0 1061--> 1062 1063* {Object} 1064 1065A hash that stores the active worker objects, keyed by `id` field. This makes it 1066easy to loop through all the workers. It is only available in the primary 1067process. 1068 1069A worker is removed from `cluster.workers` after the worker has disconnected 1070_and_ exited. The order between these two events cannot be determined in 1071advance. However, it is guaranteed that the removal from the `cluster.workers` 1072list happens before the last `'disconnect'` or `'exit'` event is emitted. 1073 1074```mjs 1075import cluster from 'node:cluster'; 1076 1077for (const worker of Object.values(cluster.workers)) { 1078 worker.send('big announcement to all workers'); 1079} 1080``` 1081 1082```cjs 1083const cluster = require('node:cluster'); 1084 1085for (const worker of Object.values(cluster.workers)) { 1086 worker.send('big announcement to all workers'); 1087} 1088``` 1089 1090[Advanced serialization for `child_process`]: child_process.md#advanced-serialization 1091[Child Process module]: child_process.md#child_processforkmodulepath-args-options 1092[`.fork()`]: #clusterforkenv 1093[`.setupPrimary()`]: #clustersetupprimarysettings 1094[`ChildProcess.send()`]: child_process.md#subprocesssendmessage-sendhandle-options-callback 1095[`child_process.fork()`]: child_process.md#child_processforkmodulepath-args-options 1096[`child_process.spawn()`]: child_process.md#child_processspawncommand-args-options 1097[`child_process` event: `'exit'`]: child_process.md#event-exit 1098[`child_process` event: `'message'`]: child_process.md#event-message 1099[`cluster.isPrimary`]: #clusterisprimary 1100[`cluster.settings`]: #clustersettings 1101[`disconnect()`]: child_process.md#subprocessdisconnect 1102[`kill()`]: process.md#processkillpid-signal 1103[`process` event: `'message'`]: process.md#event-message 1104[`server.close()`]: net.md#event-close 1105[`stdio`]: child_process.md#optionsstdio 1106[`worker.exitedAfterDisconnect`]: #workerexitedafterdisconnect 1107[`worker_threads`]: worker_threads.md 1108