5 A single instance of Node.js runs in a single thread. To take advantage of
6 multi-core systems the user will sometimes want to launch a cluster of Node.js
7 processes to handle the load.
9 The cluster module allows you to easily create child processes that
10 all share server ports.
12 var cluster = require('cluster');
13 var http = require('http');
14 var numCPUs = require('os').cpus().length;
16 if (cluster.isMaster) {
18 for (var i = 0; i < numCPUs; i++) {
22 cluster.on('exit', function(worker, code, signal) {
23 console.log('worker ' + worker.process.pid + ' died');
26 // Workers can share any TCP connection
27 // In this case it is an HTTP server
28 http.createServer(function(req, res) {
30 res.end("hello world\n");
34 Running Node.js will now share port 8000 between the workers:
36 % NODE_DEBUG=cluster node server.js
37 23521,Master Worker 23524 online
38 23521,Master Worker 23526 online
39 23521,Master Worker 23523 online
40 23521,Master Worker 23528 online
42 This feature was introduced recently, and may change in future versions.
43 Please try it out and provide feedback.
45 Also note that, on Windows, it is not yet possible to set up a named pipe
52 The worker processes are spawned using the `child_process.fork` method,
53 so that they can communicate with the parent via IPC and pass server
54 handles back and forth.
56 The cluster module supports two methods of distributing incoming
59 The first one (and the default one on all platforms except Windows),
60 is the round-robin approach, where the master process listens on a
61 port, accepts new connections and distributes them across the workers
62 in a round-robin fashion, with some built-in smarts to avoid
63 overloading a worker process.
65 The second approach is where the master process creates the listen
66 socket and sends it to interested workers. The workers then accept
67 incoming connections directly.
69 The second approach should, in theory, give the best performance.
70 In practice however, distribution tends to be very unbalanced due
71 to operating system scheduler vagaries. Loads have been observed
72 where over 70% of all connections ended up in just two processes,
73 out of a total of eight.
75 Because `server.listen()` hands off most of the work to the master
76 process, there are three cases where the behavior between a normal
77 Node.js process and a cluster worker differs:
79 1. `server.listen({fd: 7})` Because the message is passed to the master,
80 file descriptor 7 **in the parent** will be listened on, and the
81 handle passed to the worker, rather than listening to the worker's
82 idea of what the number 7 file descriptor references.
83 2. `server.listen(handle)` Listening on handles explicitly will cause
84 the worker to use the supplied handle, rather than talk to the master
85 process. If the worker already has the handle, then it's presumed
86 that you know what you are doing.
87 3. `server.listen(0)` Normally, this will cause servers to listen on a
88 random port. However, in a cluster, each worker will receive the
89 same "random" port each time they do `listen(0)`. In essence, the
90 port is random the first time, but predictable thereafter. If you
91 want to listen on a unique port, generate a port number based on the
94 There is no routing logic in Node.js, or in your program, and no shared
95 state between the workers. Therefore, it is important to design your
96 program such that it does not rely too heavily on in-memory data objects
97 for things like sessions and login.
99 Because workers are all separate processes, they can be killed or
100 re-spawned depending on your program's needs, without affecting other
101 workers. As long as there are some workers still alive, the server will
102 continue to accept connections. Node.js does not automatically manage the
103 number of workers for you, however. It is your responsibility to manage
104 the worker pool for your application's needs.
106 ## cluster.schedulingPolicy
108 The scheduling policy, either `cluster.SCHED_RR` for round-robin or
109 `cluster.SCHED_NONE` to leave it to the operating system. This is a
110 global setting and effectively frozen once you spawn the first worker
111 or call `cluster.setupMaster()`, whatever comes first.
113 `SCHED_RR` is the default on all operating systems except Windows.
114 Windows will change to `SCHED_RR` once libuv is able to effectively
115 distribute IOCP handles without incurring a large performance hit.
117 `cluster.schedulingPolicy` can also be set through the
118 `NODE_CLUSTER_SCHED_POLICY` environment variable. Valid
119 values are `"rr"` and `"none"`.
124 * `execArgv` {Array} list of string arguments passed to the Node.js
125 executable. (Default=`process.execArgv`)
126 * `exec` {String} file path to worker file. (Default=`process.argv[1]`)
127 * `args` {Array} string arguments passed to worker.
128 (Default=`process.argv.slice(2)`)
129 * `silent` {Boolean} whether or not to send output to parent's stdio.
131 * `uid` {Number} Sets the user identity of the process. (See setuid(2).)
132 * `gid` {Number} Sets the group identity of the process. (See setgid(2).)
134 After calling `.setupMaster()` (or `.fork()`) this settings object will contain
135 the settings, including the default values.
137 It is effectively frozen after being set, because `.setupMaster()` can
140 This object is not supposed to be changed or set manually, by you.
146 True if the process is a master. This is determined
147 by the `process.env.NODE_UNIQUE_ID`. If `process.env.NODE_UNIQUE_ID` is
148 undefined, then `isMaster` is `true`.
154 True if the process is not a master (it is the negation of `cluster.isMaster`).
158 * `worker` {Worker object}
160 When a new worker is forked the cluster module will emit a 'fork' event.
161 This can be used to log worker activity, and create your own timeout.
164 function errorMsg() {
165 console.error("Something must be wrong with the connection ...");
168 cluster.on('fork', function(worker) {
169 timeouts[worker.id] = setTimeout(errorMsg, 2000);
171 cluster.on('listening', function(worker, address) {
172 clearTimeout(timeouts[worker.id]);
174 cluster.on('exit', function(worker, code, signal) {
175 clearTimeout(timeouts[worker.id]);
181 * `worker` {Worker object}
183 After forking a new worker, the worker should respond with an online message.
184 When the master receives an online message it will emit this event.
185 The difference between 'fork' and 'online' is that fork is emitted when the
186 master forks a worker, and 'online' is emitted when the worker is running.
188 cluster.on('online', function(worker) {
189 console.log("Yay, the worker responded after it was forked");
192 ## Event: 'listening'
194 * `worker` {Worker object}
197 After calling `listen()` from a worker, when the 'listening' event is emitted on
198 the server, a listening event will also be emitted on `cluster` in the master.
200 The event handler is executed with two arguments, the `worker` contains the worker
201 object and the `address` object contains the following connection properties:
202 `address`, `port` and `addressType`. This is very useful if the worker is listening
203 on more than one address.
205 cluster.on('listening', function(worker, address) {
206 console.log("A worker is now connected to " + address.address + ":" + address.port);
209 The `addressType` is one of:
213 * `-1` (unix domain socket)
214 * `"udp4"` or `"udp6"` (UDP v4 or v6)
216 ## Event: 'disconnect'
218 * `worker` {Worker object}
220 Emitted after the worker IPC channel has disconnected. This can occur when a
221 worker exits gracefully, is killed, or is disconnected manually (such as with
222 worker.disconnect()).
224 There may be a delay between the `disconnect` and `exit` events. These events
225 can be used to detect if the process is stuck in a cleanup or if there are
226 long-living connections.
228 cluster.on('disconnect', function(worker) {
229 console.log('The worker #' + worker.id + ' has disconnected');
234 * `worker` {Worker object}
235 * `code` {Number} the exit code, if it exited normally.
236 * `signal` {String} the name of the signal (eg. `'SIGHUP'`) that caused
237 the process to be killed.
239 When any of the workers die the cluster module will emit the 'exit' event.
241 This can be used to restart the worker by calling `.fork()` again.
243 cluster.on('exit', function(worker, code, signal) {
244 console.log('worker %d died (%s). restarting...',
245 worker.process.pid, signal || code);
249 See [child_process event: 'exit'](child_process.html#child_process_event_exit).
253 * `worker` {Worker object}
256 Emitted when any worker receives a message.
259 [child_process event: 'message'](child_process.html#child_process_event_message).
263 * `settings` {Object}
265 Emitted every time `.setupMaster()` is called.
267 The `settings` object is the `cluster.settings` object at the time
268 `.setupMaster()` was called and is advisory only, since multiple calls to
269 `.setupMaster()` can be made in a single tick.
271 If accuracy is important, use `cluster.settings`.
273 ## cluster.setupMaster([settings])
275 * `settings` {Object}
276 * `exec` {String} file path to worker file. (Default=`process.argv[1]`)
277 * `args` {Array} string arguments passed to worker.
278 (Default=`process.argv.slice(2)`)
279 * `silent` {Boolean} whether or not to send output to parent's stdio.
282 `setupMaster` is used to change the default 'fork' behavior. Once called,
283 the settings will be present in `cluster.settings`.
287 * any settings changes only affect future calls to `.fork()` and have no
288 effect on workers that are already running
289 * The *only* attribute of a worker that cannot be set via `.setupMaster()` is
290 the `env` passed to `.fork()`
291 * the defaults above apply to the first call only, the defaults for later
292 calls is the current value at the time of `cluster.setupMaster()` is called
296 var cluster = require('cluster');
297 cluster.setupMaster({
299 args: ['--use', 'https'],
302 cluster.fork(); // https worker
303 cluster.setupMaster({
304 args: ['--use', 'http']
306 cluster.fork(); // http worker
308 This can only be called from the master process.
310 ## cluster.fork([env])
312 * `env` {Object} Key/value pairs to add to worker process environment.
313 * return {Worker object}
315 Spawn a new worker process.
317 This can only be called from the master process.
319 ## cluster.disconnect([callback])
321 * `callback` {Function} called when all workers are disconnected and handles are
324 Calls `.disconnect()` on each worker in `cluster.workers`.
326 When they are disconnected all internal handles will be closed, allowing the
327 master process to die gracefully if no other event is waiting.
329 The method takes an optional callback argument which will be called when finished.
331 This can only be called from the master process.
337 A reference to the current worker object. Not available in the master process.
339 var cluster = require('cluster');
341 if (cluster.isMaster) {
342 console.log('I am master');
345 } else if (cluster.isWorker) {
346 console.log('I am worker #' + cluster.worker.id);
353 A hash that stores the active worker objects, keyed by `id` field. Makes it
354 easy to loop through all the workers. It is only available in the master
357 A worker is removed from cluster.workers after the worker has disconnected _and_
358 exited. The order between these two events cannot be determined in advance.
359 However, it is guaranteed that the removal from the cluster.workers list happens
360 before last `'disconnect'` or `'exit'` event is emitted.
362 // Go through all workers
363 function eachWorker(callback) {
364 for (var id in cluster.workers) {
365 callback(cluster.workers[id]);
368 eachWorker(function(worker) {
369 worker.send('big announcement to all workers');
372 Should you wish to reference a worker over a communication channel, using
373 the worker's unique id is the easiest way to find the worker.
375 socket.on('data', function(id) {
376 var worker = cluster.workers[id];
381 A Worker object contains all public information and method about a worker.
382 In the master it can be obtained using `cluster.workers`. In a worker
383 it can be obtained using `cluster.worker`.
389 Each new worker is given its own unique id, this id is stored in the
392 While a worker is alive, this is the key that indexes it in
397 * {ChildProcess object}
399 All workers are created using `child_process.fork()`, the returned object
400 from this function is stored as `.process`. In a worker, the global `process`
403 See: [Child Process module](
404 child_process.html#child_process_child_process_fork_modulepath_args_options)
406 Note that workers will call `process.exit(0)` if the `'disconnect'` event occurs
407 on `process` and `.suicide` is not `true`. This protects against accidental
414 Set by calling `.kill()` or `.disconnect()`, until then it is `undefined`.
416 The boolean `worker.suicide` lets you distinguish between voluntary and accidental
417 exit, the master may choose not to respawn a worker based on this value.
419 cluster.on('exit', function(worker, code, signal) {
420 if (worker.suicide === true) {
421 console.log('Oh, it was just suicide\' – no need to worry').
428 ### worker.send(message[, sendHandle])
431 * `sendHandle` {Handle object}
433 Send a message to a worker or master, optionally with a handle.
435 In the master this sends a message to a specific worker. It is identical to
436 [child.send()](child_process.html#child_process_child_send_message_sendhandle).
438 In a worker this sends a message to the master. It is identical to
441 This example will echo back all messages from the master:
443 if (cluster.isMaster) {
444 var worker = cluster.fork();
445 worker.send('hi there');
447 } else if (cluster.isWorker) {
448 process.on('message', function(msg) {
453 ### worker.kill([signal='SIGTERM'])
455 * `signal` {String} Name of the kill signal to send to the worker
458 This function will kill the worker. In the master, it does this by disconnecting
459 the `worker.process`, and once disconnected, killing with `signal`. In the
460 worker, it does it by disconnecting the channel, and then exiting with code `0`.
462 Causes `.suicide` to be set.
464 This method is aliased as `worker.destroy()` for backwards compatibility.
466 Note that in a worker, `process.kill()` exists, but it is not this function,
467 it is [kill](process.html#process_process_kill_pid_signal).
469 ### worker.disconnect()
471 In a worker, this function will close all servers, wait for the 'close' event on
472 those servers, and then disconnect the IPC channel.
474 In the master, an internal message is sent to the worker causing it to call
475 `.disconnect()` on itself.
477 Causes `.suicide` to be set.
479 Note that after a server is closed, it will no longer accept new connections,
480 but connections may be accepted by any other listening worker. Existing
481 connections will be allowed to close as usual. When no more connections exist,
482 see [server.close()](net.html#net_event_close), the IPC channel to the worker
483 will close allowing it to die gracefully.
485 The above applies *only* to server connections, client connections are not
486 automatically closed by workers, and disconnect does not wait for them to close
489 Note that in a worker, `process.disconnect` exists, but it is not this function,
490 it is [disconnect](child_process.html#child_process_child_disconnect).
492 Because long living server connections may block workers from disconnecting, it
493 may be useful to send a message, so application specific actions may be taken to
494 close them. It also may be useful to implement a timeout, killing a worker if
495 the `disconnect` event has not been emitted after some time.
497 if (cluster.isMaster) {
498 var worker = cluster.fork();
501 worker.on('listening', function(address) {
502 worker.send('shutdown');
504 timeout = setTimeout(function() {
509 worker.on('disconnect', function() {
510 clearTimeout(timeout);
513 } else if (cluster.isWorker) {
514 var net = require('net');
515 var server = net.createServer(function(socket) {
516 // connections never end
521 process.on('message', function(msg) {
522 if(msg === 'shutdown') {
523 // initiate graceful close of any connections to server
530 This function returns `true` if the worker's process has terminated (either
531 because of exiting or being signaled). Otherwise, it returns `false`.
533 ### worker.isConnected()
535 This function returns `true` if the worker is connected to its master via its IPC
536 channel, `false` otherwise. A worker is connected to its master after it's been
537 created. It is disconnected after the `disconnect` event is emitted.
543 Similar to the `cluster.on('message')` event, but specific to this worker.
545 This event is the same as the one provided by `child_process.fork()`.
547 In a worker you can also use `process.on('message')`.
549 As an example, here is a cluster that keeps count of the number of requests
550 in the master process using the message system:
552 var cluster = require('cluster');
553 var http = require('http');
555 if (cluster.isMaster) {
557 // Keep track of http requests
559 setInterval(function() {
560 console.log("numReqs =", numReqs);
564 function messageHandler(msg) {
565 if (msg.cmd && msg.cmd == 'notifyRequest') {
570 // Start workers and listen for messages containing notifyRequest
571 var numCPUs = require('os').cpus().length;
572 for (var i = 0; i < numCPUs; i++) {
576 Object.keys(cluster.workers).forEach(function(id) {
577 cluster.workers[id].on('message', messageHandler);
582 // Worker processes have a http server.
583 http.Server(function(req, res) {
585 res.end("hello world\n");
587 // notify master about the request
588 process.send({ cmd: 'notifyRequest' });
594 Similar to the `cluster.on('online')` event, but specific to this worker.
596 cluster.fork().on('online', function() {
600 It is not emitted in the worker.
602 ### Event: 'listening'
606 Similar to the `cluster.on('listening')` event, but specific to this worker.
608 cluster.fork().on('listening', function(address) {
609 // Worker is listening
612 It is not emitted in the worker.
614 ### Event: 'disconnect'
616 Similar to the `cluster.on('disconnect')` event, but specific to this worker.
618 cluster.fork().on('disconnect', function() {
619 // Worker has disconnected
624 * `code` {Number} the exit code, if it exited normally.
625 * `signal` {String} the name of the signal (eg. `'SIGHUP'`) that caused
626 the process to be killed.
628 Similar to the `cluster.on('exit')` event, but specific to this worker.
630 var worker = cluster.fork();
631 worker.on('exit', function(code, signal) {
633 console.log("worker was killed by signal: "+signal);
634 } else if( code !== 0 ) {
635 console.log("worker exited with error code: "+code);
637 console.log("worker success!");
643 This event is the same as the one provided by `child_process.fork()`.
645 In a worker you can also use `process.on('error')`.