Run a NodeJS Application on Multiple CPU Cores Using Cluster
Introduction
A single instance of a Node.js application runs on only one thread and, therefore, doesn't take full advantage of multi-core systems. There will be times when you may want to launch a cluster of Node.js processes to utilize each CPU core on a local machine or production server.
Luckily, Node.js has a core module named Cluster that helps us run a Node.js application using all the CPU cores on a machine.
In this article, we'll create a basic Node.js application and run an instance of it on each CPU core the host machine has. By doing so, the throughput of the Node.js application will increase along with each additional instance that is created.
Let's get started!
Table of Contents
Create a Node.js Application
Before anything else, we need to create a Node.js application to run. For demonstration purposes, let's create an application that runs a simple HTTP server.
Open a Node.js file and add this code to it:
Node.js
 
const http = require("http")
 
const PORT = 5000
 
const server = http.createServer((req, res) => {
  res.end("Hello there!")
})
 
server.listen(PORT, (err) => {
  if (err) {
    console.log(err)
  } else {
    console.log(`Server is listening on port ${PORT}`)
  }
})
The first thing we do is import the HTTP core module. Since it's a Node.js core module, we don't need to install anything before we use it.
Then we define what port we want our basic HTTP server to run on and store it in the PORT variable. In this case, we'll run the application on port 5000.
Next, we use the http.createServer() method to create an HTTP server and have it respond with "Hello there!" whenever it receives a request.
Last, we tell the HTTP server to listen on the 5000 port we specified with the server.listen() method.
Awesome, now we have a basic Node.js application up and running. In the next step, we'll get it running on multiple CPU cores.
Run the Application on Multiple CPU Cores
Now we're ready to get this thing running on more than one CPU!
Open your Node.js file and update the code to this:
Node.js
 
const http = require("http")
const os = require("os")
const cluster = require("cluster")
 
const PORT = 5000
 
const numOfCpuCores = os.cpus().length
 
if (numOfCpuCores > 1) {
  if (cluster.isMaster) {
    console.log(`Cluster master ${process.pid} is running.`)
 
    for (let i=0; i < numOfCpuCores; i++) {
      cluster.fork()
    }
 
    cluster.on("exit", function(worker) {
      console.log("Worker", worker.id, " has exitted.")
    })
  } else {
    const server = http.createServer((req, res) => {
      res.end("Hello there!")
    })
 
    server.listen(PORT, (err) => {
      if (err) {
        console.log(err)
      } else {
        console.log(`Server is listening on port ${PORT} and process ${process.pid}.`)
      }
    })
  }
} else {
  const server = http.createServer((req, res) => {
    res.end("Hello there!")
  })
 
  server.listen(PORT, (err) => {
    if (err) {
      console.log(err)
    } else {
      console.log(`Server is listening on port ${PORT} and process ${process.pid}.`)
    }
  })
}
A lot is going on in the code, so let's go through each part.
The first thing we do is require() the express npm package and the two Node.js core modules os and cluster.
Next, we create a PORT variable and assign it a value of 5000. We'll use this variable later on in our code.
Then we create a variable called numOfCpuCores to represent the number of CPU cores the system has. We use the os.cpus().length method to get that number.
Check out the Node.js documentation for more info on the os.cpus() method.
Using the numOfCpuCores value, we create an if...else statement that checks whether or not the system has more than one CPU core. If the number of CPUs is greater than 1, we move on with creating the cluster. But if there is only one CPU on the machine the code is running on, we start our Node.js application the same way we did in the first step of this tutorial on the single CPU core.
Assuming our machine has more than one CPU, the first thing we do is create another if...else statement that checks whether or not this is the first process in the cluster that has run. We check that with the cluster.isMaster() method that returns either true or false.
If that is the first process that has run, we use cluster.fork() to spawn a new worker process for each of the CPU's that exist on the machine. And we also add an event listener that will log a message when a worker exits so we know when something goes wrong or unexpected.
The role of the master process is to listen to our HTTP server's port and load balance all of the requests among the workers.
Once all of our workers are spawned, we create a new instance of our Node.js application on each of the workers we created. For example, 2 instances of the application will be created if your machine has 2 CPU cores.
When you run the application, you should see this or something similar logged to the console:
Output
 
Cluster master 30892 is running.
Server is listening on port 5000 and on process 30899.
Server is listening on port 5000 and on process 30904.
Server is listening on port 5000 and on process 30898.
Server is listening on port 5000 and on process 30911.
The output will vary depending on how many CPUs your system has.
Congratulations! You now have a Node.js application running on multiple CPUs!
Conclusion
The cluster module gives Node.js the much-needed ability to use the entire power a CPU provides by allowing us to easily create child processes. And it also does a ton of work in the background to communicate between the master and worker processes.
After working through this article, you should now know how to use that module to run a Node.js application on multiple CPU cores. With this knowledge, you will be able to better manage and scale your applications.
Happy coding and thanks for reading!
Have any questions or comments about this article? You can contact me via email at nick@coderrocketfuel.com or on Twitter at @CoderRocketFuel.
If you enjoyed this free content, please consider supporting what I do by Buying Me a Coffee.