How Node.js handles concurrency

How Node.js handles concurrency

What is Node.js?

Node.js is an open-source cross-platform JavaScript environment that runs on Chrome's V8 engines. Node.js is a tool that can be used in almost any kind of project! As Node.js can help in developing highly scalable server-side applications.

If you don’t have basic knowledge about Node.js I would suggest you go through it's basics here.

But as Node.js runs on single-threaded event loop architecture, so you might be wondering about how it can handle concurrency. But before we know why let’s learn more about concurrency.

What is concurrency?

Concurrency in basic terms means the ability of the program to run more than one task at a time. But some of you might get confused between concurrency and parallelism. Basically, in parallelism different parts of the program execute one task at the same time. But in concurrency tasks with different programs are executed at the same time.

concurrency vs parallelism.png

Though it’s pretty basic to know how concurrency takes place in web apps if you have some experience developing them. But those who are new to development might be wondering okay we know what is concurrency but how does it affect our web apps? So let me explain to you with an example:

If a user requests multiple data from the server; now the server will get the data from the database. Let’s suppose this process takes 5 seconds i.e. server will send the response to the user of their one request in 5 seconds and if we are processing the requests in sequential order then the time taken to process all the requests will be \(5*n\) seconds (n being the number of requests if the time to process 1 request is same as others).

But if we handle the requests concurrently, it will take \(5 + m*n\) seconds (n being the time to process one request and m being the number of requests if the time to process 1 request is the same as others).

concurrency in webapp.png

What Node.js provides?

Node.js uses an event loop to maintain concurrency and perform non-blocking I/O operations. So when it starts, it initializes an event loop. The event loop functions as a queue also known as an event queue so that it can execute tasks in FIFO. But a task is only executed when there’s no ongoing task in the call stack. The event loop continuously checks the call stack to check if there is any task that needs to be run. So whenever the event loop finds any function, it adds it to the stack and runs it in that order.

Example

So let’s continue with the above example of multiple requests but we will limit the request to 4 so if we are using our old simple JavaScript then it would run it in the sequential manner so it will take 20 seconds to send the results whereas if we use Node.js it will use event loop and process the requests in sequential order so it will take 9 seconds to send the results of all the requests.

You all might be wondering okay now we know Node.js achieves concurrency by events loop but what does it actually look like? So first let’s see how multiple requests will get processed in Node.js with an event loop.

eventloop.png

Now let’s see the functioning of all of the things I mentioned above using the following code

const myFunction = () => {
    console.log("Response of first request inside this function");
    setTimeout(function(){
        console.log("Response of second request inside this function");
    },5000);
    console.log("Response of third request inside this function");
}

console.log("Response of the request made outside the function and before it's call");
myFunction();
Output in JS:
Response of the request made outside the function and before it's call
Response of first request inside this function
Response of second request inside this function
Response of third request inside this function

So from this, you can see the flow of requests in sequential order so what’s happening here is first the request made before the function will be executed after that it will get into the function and the first request will be processed. After that, it will move to the second request and here it takes 5 seconds to get processed so it will process this request after 5 seconds and will move to the third and final request i.e. the third request and it will process it and all the requests will be executed. So you might notice that we are getting stuck to the one request no matter how much time it will take to execute it.

Output in Node.js:
Response of the request made outside the function and before it's call
Response of first request inside this function
Response of third request inside this function
Response of second request inside this function

Here you can see the flow of requests in concurrent order so the first console statement console.log(Response of the request made outside the function and before it's call)will be pushed into the stack; get logged and popped off the stack. Now the function myFunction() will be called and pushed into the stack. Then the first statement console.log("Response of first request inside this function") in the function will be called and logged and pushed out of the stack. Then the runtime goes to setTimeout() function and as it works in a web API it goes to browser and a timer of 5 seconds i.e. it will execute that statement after the timer ends and then it goes popped out of the stack. But in the meantime, next statement is pushed to the call stack and so Response of third request inside this function will be logged to the console. As 5 seconds are completed browser will push that console.log(Response of second request inside this function) statement will get pushed to the event queue. Now event loop checks whether the call stack is empty or not and then pushes it into the call stack so Response of second request inside this function will get logged to the console and the function will be popped out of the stack. Now the function is completed and there are no more events left.

Hope you now understand how Node.js handles concurrency.

If you have not explored frameworks of Node.js I would recommend you to do so. Some of the commonly used frameworks are Express.js, Nest.js, Nextjs, Socket.io, Meteor, Fastify, and Gatsby. You will also get some amazing blogs on those as well so don’t forget to connect with me for regular updates!

Did you find this article valuable?

Support Arjun Aghera by becoming a sponsor. Any amount is appreciated!