• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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