How to run the Node.js server on every CPU core?

October 30, 2020 - 4 min read

To handle more traffic and load on a Node.js server we might need to spin up more instances of the Node.js server to many cores in a CPU because a single instance of a Node.js server runs on a single thread which may not be enough on critical times.

Fortunately, the Spinning up of more processes is fairly easy in Node.js.

There are 2 things we need to understand:

  • Master process (or Parent Process): This is the main process
  • Child process: These are originated from the master process and uses the same script of the master process to execute. Simply put, the child process is like a copy of the master or parent process.

See this to know more on Parent and Child Process

The basic idea is to spin many instances or child processes of the server from a master process so that the child process will be able to handle requests.

First, we need to get the cluster native module in Node.js. The cluster module is for spinning up more child processes.

// cluster
const cluster = require("cluster");

Then we need to get the os module to count the number of CPUs or cores present in the system. We can get the number of cores by first calling the cpus() method and using the length property returned from the function.

// cluster
const cluster = require("cluster");
// os
const numberOfCores = require("os").cpus().length;

Now we need to make as many child processes from the master process equal to the number of CPU cores in the system.

To check if the current process is the master process we can use the isMaster boolean property in the cluster module like this,

// cluster
const cluster = require("cluster");
// os
const numberOfCores = require("os").cpus().length;

// check if the current
// process is the
// master process
if (cluster.isMaster) {
  // if the current process
  // is the master process
  // make child process
} else {
  // if it is not master then
  // start listening for requests from users
  // this section of code is used by child processes
}

Let' use a loop and use the cluster.fork() method inside it to make child processes for all the CPU cores in the system.

// cluster
const cluster = require("cluster");
// os
const numberOfCores = require("os").cpus().length;

// check if the current
// process is the
// master process
if (cluster.isMaster) {
  // if the current process
  // is the master process
  // make child process
  for (let i = 0; i < numberOfCores; i++) {
    // fork child process
    cluster.fork();
  }
} else {
  // if it is not master then
  // start listening for requests from users
  // this section of code is used by child processes
}

Finally, we need to listen for requests from the child processes. Let' use an expressjs server.

// cluster
const cluster = require("cluster");
// os
const numberOfCores = require("os").cpus().length;
// express
const express = require("express");
const app = express();

// check if the current
// process is the
// master process
if (cluster.isMaster) {
  // if the current process
  // is the master process
  // make child process
  for (let i = 0; i < numberOfCores; i++) {
    // fork child process
    cluster.fork();
  }
} else {
  // if it is not master then
  // start listening for requests from users
  // this section of code is used by child processes
  app.get("/", (req, res) => {
    res.send("Hello from a child process...");
  });

  app.listen(3000, () => {
    console.log("Child process started...");
  });
}

That's it. We have successfully scaled our Node.js server in the simplest and basic way 😃.

Feel free to share if you found this useful 😃.