Node.js is single threaded yet successful

Node.js is single threaded and operates asynchronously using the "Single Threaded Event Loop" architecture and handles multiple concurrent clients efficiently without multithreading. Node.js is actually designed to build distributed applications with many nodes and that's the reason why it's called Node. Actually, the main event loop is single threaded but Node.js uses multiple threads in the background to execute asynchronous code.

Node.js is non-blocking which means that all the callbacks or functions are delegated to the event loop and are executed by different threads. This means that when other processes are executing in a concurrent manner, the event loop continues to run as non-JavaScript operations. This way the tasks are executed asynchronously.

Needless to say that Node.js is extremely good at handling multiple requests concurrently using a single thread model. This is called "asynchronous cooperative multitasking".

That's the reason why we switched to a single-threaded approach to handle asynchronous code and I'm sure it will definitely stay for long.

Management of asynchronous code in Node.js

A lot of times we have dealt with multithreading and preemptive multitasking scenarios but the first time we encountered cooperative multitasking using Node.js was when creating a User Module at the earlier stage of our product creation.

This module deals with managing different user roles and permissions and consolidates the respective entitlement of users of different levels (like Admin and User). We understood that asynchronous code in Node.js can be handled in 3 possible ways:

1. Callbacks

Callback is an executable code that is passed as an argument to another code and is expected to execute (or call back) at a specific time. Callbacks make sure that certain code doesn't execute until another code is finished its execution.


- Callbacks are simple to understand and easy to create

- Only fewer objects are created and garbage collected


- Does not scale to even moderately complex asynchronous code

- Resulting code can be hard to read and debug

2. Using Async/Await with Promises

The async/await pattern structures an asynchronous, non-blocking function similar to a synchronous function. It provides opportunities to the program to execute other code while waiting for a long-running asynchronous task to complete. The await keyword within the async function returns a promise value that ensures the current function is completed before calling the subsequent function.


- Things that would normally take many functions to compose can now be composed in one function. So, visual complexity is greatly reduced and the look and feel is simple.

- No longer getting stuck with endless `then` chains

- Try/catch blocks work smoothly in the async code


- Things that would normally take many functions to compose have to now be composed in one function. Since several functions are joined together into one function, multiple pieces of code run at different times without any explicit boundaries.

- If you really want to use async/await, you need to transpile it with something like Babel

3. Using Promises

Promises are abstractions provided that give us a way to express ourselves synchronously when writing asynchronous code. A promise returns a value that is either resolved or the reason why that's not resolved (for example, when a network error occurs). A promise can be in any one of the following states:

States of a Promise

Pending: async operation is incomplete and promise does not have a value yet

Fulfilled: async operation is completed and promise has a value

Rejected: async operation has failed and promise will never get fulfilled.


- No extra libraries are needed since Promises are native

- Compositional pipeline of functions

- Provides easier error handling

- Avoids callback hells

- Increases code maintainability


- Not available on all JS engines

- Due to the runtime overhead of monitoring the state of a Promise, they are slower than callbacks

As discussed, there are 3 different ways to handle asynchronous code in Node.js and based on the problem's context, users can adopt any one of the above-mentioned solutions. However, we went on to choose a fairly different solution (not form the list) to handle our scenario and you can check it out in the successive section.

Start 1 2 3 End

Related Blog

Contact Us

*All the fields are mandatory.

+1 732 737 9188