Node.js Cluster Module: Improve Node.js Code Performance

Node.js programs, by default run in single thread mode. This means that by default your Node.js code is running on a single core of your processor.

I believe every computing machine nowadays comes up with multi-core processor and you should take advantage of them.

So is your Node.js application taking advantages of those cores and utilizing the resources?

Well if you are not running it on the cluster, then probably you are wasting your hardware capabilities.

In this tutorial, I am going to explain one of the awesome features of Node.js which allows you to utilize all the cores of your machine. It’s called “Cluster Module”.

What is clustering ?

Clustering in Node.js allows you to create separate processes which can share same server port. For example, if we run one HTTP server on Port 3000, it is one Server running on a Single thread on a single core of the processor.

But I want to take advantage of all core available on my machine. So I will cluster my application and run them on all cores. So if I run one server on Port 3000 by having 4 core processor then actually I am running 4 servers all are listening to Port 3000.

So if one server goes down the other is there to take the place of it, also in peak load of traffic, Node will automatically allocate the worker to particular process so basically it does internal load balancing very efficiently.

Code which does this Magic.

The code shown below allows you to cluster your application. This code is official code represented by Node.js.

If you observe the code, we are loading Cluster module in the first line. Then we are counting how many cores do we have on our machine. Then in “if” condition, we are checking that if its Master process then creates the copy of the same process by the number of core times.

If it is not the Master machine then basically run our normal Node program. So there would be one process which is master which in turn create processes number of core time.

In my case, i have Intel i5 consist of 4 core processor. If i run this code, i will get this output in terminal.

Our project:

I have covered Express so far as default HTTP server. So for demo purpose i am going to build simple Express program using clustering.

//change this line to Your Node.js app entry point.
require("./app.js");}

So now to run your server type,

node cluster.js

You should see this output with above code.

Performance analysis:

If we tweak above code little bit and add line to show Process ID which serve the request, we will get following response if we try to access localhost:3000 in different browser or client.
Notice anything in process IDs, Since i am running this code on Localhost most i can find to prove clustering is this only, although if we run this code on production workload we may get different response.

For example, suppose you are getting 1000 request in a minute to Port 8000. Before clustering, all request will be served by this instance of the program.

After clustering, you have 4 copy of your program running and listening on Port 3000. So just for example, in one minute 1000 request will be divided to 250 for each core. So together performance will increase.

This is just, for example, internal load balancing is done by the node itself.

Conclusion:

In the local environment, you may not be able to judge exact performance improvement but I believe in production workload this technique will help you a lot to improve the throughput of your System and utilize resources at the top.

Also, a quick tip, if you are running your code in production then I highly recommend PM2 with keymetrics. PM2 supports clustering in a simple command line. Check out the complete article here.

This is all about clustering in node.js. Share your views in comments.

Any special use of sticky load balancing ? My concern is load balancing is all about distributing traffic or load from one payload to other (if available) and making sure that no node gets more load than its suppose to.

First, I want to say that this was a fantastic article, and many thanks to the author.

As to the sticky load balancing, in my experience, sticky load balancing has come into play in e-commerce situations where things like shopping carts are heavily dependent upon maintaining a given TLS session. For example, in our environment we have dozens of e-commerce servers behind a load balancer. If a user was interacting with Server A and then suddenly be directed to Server B the next time it hit the load balancer, it would break the way our e-comm folks have the shopping cart setup. I am not saying that I agree with how they have it setup (I am in security architecture, not e-comm), but that is how they do it. In our case I have recommended setting up a load balanced TLS session cache cluster so any server could pick up for any other server’s TLS session as needed, eliminating the need for sticky load balancing.

There are other cases, I am sure, but that was the first thing that came to mind as I read the post.

Hi Kurt,
Thanks for the nice explanation about scenario. I seriously had no clue that we can use sticky balancing in e-commerce. Idea of TLS caching cluster is really impressive. Thanks again for comment.

Hi Shahid,
One small doubt, in first screen you use the `Cluster.workers[id].process.pid`. Form where do you get this information that process only have `pid`. Because I use any other name, it will return `undefined`. Please explain me and explain me from & how can we gather those info.
Thanks

maybe just a stupid question, but when will the else part will execute, suppose first cluster is master cluster and it will fork the child process, now control is at end of the file, so when will require(app) line will execute.