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