Blocking vs Non-Blocking in NodeJS – What’s the Difference?

Blocking vs Non-Blocking in NodeJS – What’s the Difference? This article will introduce what Node.js is and next, we will explain its blocking vs non-blocking feature.  

What is Node.js server?

Node.js is a runtime environment and it’s main purpose is to execute JavaScript. Developed on Chrome’s V8 Engine, which is the JavaScript execution engine. It is event driven, non blocking asynchronous I/O model. Node.js helps in the development of real time network applications. 

Furthermore, Node.js server runtime is built on top of a programming language, JavaScript. In 2009, when Ryan Dahl created Node he noticed that I/O was not being used correctly and it has blocked the entire process because of synchronous programming. The non blocking IO feature for the asynchronous functionality was introduced. It kept the server from waiting on data to be returned before being able to move on to other tasks.

More importantly, are you wondering what non blocking I/O and blocking I/O is? Firstly, blocking refers to the blocking of further operation until the current operation finishes. Blocking methods are executed synchronously. 

Blocking vs Non Blocking in NodeJS

The biggest benefit you get from Node’s Event Loop is non blocking Input/Output (I/O).

What is IO?

When the threads in a server process a request from a computer, the processing part of the request has a part that requires active attention and a part of the request that doesn’t require active attention.

The part that requires attention is called the CPU work because it requires the computer’s central processing unit to spend time thinking and computing results actively.

The part that doesn’t require active attention is called the I/O or input/output because it involves waiting for something else to provide input or send output.

Examples of I/O are waiting to read a file from the file system or waiting while making network requests to another server.

CPU is active computing or thinking, and IO is waiting for something else to happen to make things more concrete.

We understand the basics of I/O so let’s explain the non blocking and blocking operating models separately.

Blocking IO Node.js

Blocking vs Non-Blocking in NodeJS let us understand what blocking IO is. The term blocking originates from the OS process model. A multitasking OS labels individual processes with a state depending upon the readiness of the process to get executed.

It is labeled blocked when the process is not ready for processing but is waiting for an IO event. Blocking I/O means that the thread is stuck or blocked, waiting for the I/O to finish before it can keep going.

A blocking system call turns the process to enter a blocked state and the control is let back only after the I/O event happens after waiting. In the NodeJS environment, the files ystem contains fs.xSync methods to provide the blocking version.

				
					const fs = requires("fs");
const contents = fs.readFileSync("file.txt", "utf8");
console.log(contents);
				
			

The file system operation’s blocking version ensures that the call doesn’t return until the I/O is completed.

Once completed, the call returns and the operation results are the return value.

Then the results of the blocking call are returned synchronously. A lot more waiting and unnecessary latency arise in the case of blocking I/O, which is one of the significant drawbacks of blocking I/O.

Non blocking IO Node.js

Next part of our blog about Blocking vs Non-Blocking in NodeJS is Non-blocking I/O. It allows the thread to save time by switching requests whenever a request is doing I/O.

The non-blocking IO functionality increases the practical work that a single thread can do. It enables the thread not to get stuck or blocked, waiting for the request to finish while doing I/O. Unlike blocking I/O, it doesn’t wait for the I/O to complete.

A non-blocking I/O operation doesn’t allow the process to be on the back burner at an OS level; instead, it continues to run. When the non blocking call starts the operation, it leaves the OS to return immediately with no results. Different means are used to complete the I/O operation.

To ensure that the non blocking I/O is completed, programs interact with the OS using polling. It enables the program to ask the OS the status of the I/O operation. If any of the I/O operations is marked completed, it processes those.

With Javascript, you can use an approach known as a callback. A non blocking Javascript call provides a callback function during the completion of the function. NodeJS uses OS level polling with worker threads for operations that resist polling.

Node translates these mechanisms into different Javascript callbacks.

Using non blocking I/O enables a single process to handle multiple requests at the same time. The time wasted during the blocking I/O operations can serve different requests. Node core APIs and libraries offer non blocking operations. Look at the filesystem example below for non blocking calls.

				
					const fs = requires("fs");
fs.readFileSync("file.txt", "utf8", (err, data) => {
 console.log(data);
});
				
			

The readFile call returns with no results. The current code block comes back and after all the I/O operations are completed, the callback is called. The nonblocking calls return the results asynchronously.

Blocking vs Non blocking Nodejs

The blocking call doesn’t return and waits until the I/O operation is executed. When the I/O operation has been completed, the results of a blocking call are returned synchronously. During the wait, no other task takes place in that process.

When it comes to non blocking calls, they return with no results and find alternate means to check for the operation’s completion. More processing can be done simultaneously while waiting for the I/O process to be executed.

The NodeJS DevOps development tools  enables developers with different core APIs and libraries to use non blocking calls to develop and build robust applications that can use I/O waiting time to complete more requests.

It increases the speed and performance of the applications and helps to drive better and quicker results than blocking I/O calls.

Why is the Non-blocking I/O not the standard?

You should understand that non blocking I/O seems better and more efficient but why it is not the standard and why not used in different languages?

When web development back end  first became popular in languages like Perl, PHP and later on like Ruby on Rails and Python, the language model didn’t easily allow non-blocking I/O.

It was because the traditional web serving techniques are focused on the thread model where one thread handles only one request in the server, in an I/O operation, the request processing entails unused resources and limits the scalability.

It is possible to use non blocking I/O in some of the above listed and other languages like Rust, Go, Java and Scala.

That’s why NodeJS was introduced to make the non blocking I/O easier to adopt. It enables the software to multi task and eliminate waiting for the I/O operation to execute.

In NodeJS a single thread handles several concurrent connections that increase the software’s efficiency. The use of libuv libraries and a fixed sized thread pool enables execution of non-blocking I/O operations in parallel during the waiting in the NodeJS.

But there are downsides of non-blocking I/O that can’t be ignored.

Cons of non blocking IO Node.js

Non blocking I/O operation improves the software’s speed and processing, but there are some disadvantages.

It’s only effective for I/O heavy workloads. In workloads that have more I/O work than CPU work, the efficiency gain from non-blocking I/O is much higher, as you might expect.

On the other side, if the workload is predominantly CPU, the non blocking I/O won’t help very much. It is essential when working with NodeJS servers because they only have one thread and will get stuck quickly with CPU heavy workloads.

The workload dependency related to the non-blocking I/O of NodeJs is why it excels for applications like sending lots of network requests but isn’t as strong for other applications like machine learning ,which involves a lot of CPU power .

As an alternative, developers use servers with blocking I/O and lots of threads to handle high traffic to achieve their desired results and bypass the drawbacks of non-blocking I/O.

With more understanding of blocking and non-blocking I/O in NodeJS, you can filter out which operation you want to use or not to use based on your application goals, traffic handling and other requirements.

Both the operations offer different benefits and can be integrated into your application based on what you want.

Blocking vs Non-Blocking in NodeJS – What’s the Difference? Conclusion

Node.js allows two funcions with I/O operations: synchronous, or blocking operations; and asynchronous, or non-blocking functions. The fs module (synchronous or asynchronous) explores what happens in the Event Loop in order to allow for a single threaded application to handle non-blocking asynchronous I/O.

 

We understand that the asynchronous callbacks of I/O operations are processed during the I/O callbacks phase of the Event Loop. By using these asynchronous tools of Node.js, we can continue with the main code execution while heavy file and network operations are handled concurrently by libUV.

Avatar for Hitesh Jethva
Hitesh Jethva

I am a fan of open source technology and have more than 10 years of experience working with Linux and Open Source technologies. I am one of the Linux technical writers for Cloud Infrastructure Services.

5 1 vote
Article Rating
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x