Further Improve your Node.js application performance.
Although node.js is a single-threades programming language, it is consideres one of the most performant one. Competing very well with other multi threaded languages. However, if we look deeper into the workings we will identify that Node.js, by default, doesn’t utilise all the available cores of the CPU. In fact, it manages to work with only a single core engine.
The need for Node.js clustering:
If the system we are running has multiple cores then it’s best to utilise them to the fullest. There are scenarios where our Node application might have to handle a large amount of load. In such cases, distributing load across multiple cores is certainly more efficient than making use of a single core. Furthermore, some requests might remain idle until the previous execution has completed because of blocking code in the code-base.
Node.js clusters in short:
This is where the cluster module of Node.js comes into the picture. In essence, it helps to leverage the multi-core architecture and allows to spawn child processes, in other words, known as workers in the Node world. They have their own memory and event loop and also run on the same server port. We can create workers equal to the number of CPU cores and achieve true definition of parallelism.
In order to understand how to make use of clusters, let’s create a simple Node server (using express.js) which basically calculates the number of even numbers existing within 200000:
Here, sending a request to GET localhost:3000/api/even and at the same time, immediately sending another request to GET localhost:3000/ would practically be able showcase what was just explained above. The second request to GET localhost:3000/ only sends back a response after execution of the first api call completes.
In reality, this will only result in bad response time and therefore, a bad user experience.
Nonetheless, Node.js clustering can help resolve this:
Clusters basically follow the same master and child architecture. The master spawns and manages the child process while the child process does the relevant work.
The same program as above is translate to use node clusters. But now, the same experiment shows that the second response to get localhost:3000/ is receives in no time while the first request to get localhost:3000/api/even is still being processes.
In the program above, we use the cluster module and check if the current cluster is master. If it’s a master cluster then we create workers equal to the number of CPU cores. If the cluster is a worker then it performs the relevant functions, in this case, calculating even numbers.
To illustrate this better, we can also take a look at the performance comparison done based on the increasing load request:
Credit: Dannish Siddiq’s post
This picture very well depicts the improvements of multi-threaded clusters. The time taken increases exponentially in a single threaded service with the number of requests. But in the multi-threaded service the response time increases but not so drastically.
Communication between processes:
When we start using clusters in a real world application, we will realise that the communication between the master and workers is one of the vital mechanisms to implement clustering efficiently.
The communication between the masters and the workers are purely event driven. Master can send a common message across all worker threads or else send messages to specific worker.worker.send() and worker.on() are uses respectively for sending and receiving messages.
Likewise, workers can also send and receive messages to and from the master process. process.send() and process.on() are used respectively.
Conclusion and suggestions:
- In today’s ever progressing world, technical improvements have become a must to stay relevant in the sector. High performance is considered one of the major metric to rate a product. Particularly, for Node.js developers, clusters can be one of the mechanisms to provide a performance boost to their already efficient application. Services that perform CPU extensive operations can benefit most from using clustering.
- Equally important, clusters can also help in providing zero down-time servers. The master process runs the whole time and invokes the child processes. In any event of change being made to the application, the older versions would still be running while the new change is being loaded. Thereby, reducing or even eliminating the changes of down-time.
- They are a native Node.js module and are very easy to implement or even migrate to from an existing application.
- I feel like REST API’s that have high frequency of calls will benefit most this concept.
- Despite the benefits highlighted above, we should keep in mind that in case the operations are not very CPU intensive then Node.js is very well capable of handling it by default. Clustering is not suggested for such applications as the extra resource allocation might remain unutilised.
Thanks for reading!!
To learn more about Engineering topics visit – https://engineering.rently.com/
Get to know about Rently at https://use.rently.com/
Senior Software Engineer
| Node.js | React Native |