# Blocking vs Non-Blocking Code in Node.js

Blocking code stops the execution of other code until the current task finishes.

This means:

*   the program waits
    
*   nothing else executes meanwhile
    

In blocking operations:

***the main thread remains busy until the task completes.***

* * *

**Example**

```javascript
console.log("start");

for(let i = 0; i < 1e9; i++) {}

console.log("end");
```

Output:

```shell
start
(wait...)
end
```

The heavy loop blocks execution.

* * *

### What Non-Blocking Code Means

Non-blocking code allows other code to continue running while a task is being processed.

Instead of waiting:

*   the task runs asynchronously
    
*   execution continues
    

This is one of the core concepts behind Node.js.

* * *

**Example**

```javascript
console.log("start");

setTimeout(() => {
  console.log("done");
}, 2000);

console.log("end");
```

Output:

```shell
start
end
done
```

The timer does not block the main thread.

* * *

### Why Blocking Slows Servers

Servers need to handle many requests at the same time.  
If one request blocks execution:

*   other users must wait
    
*   performance becomes slow
    
*   scalability decreases
    

Blocking operations can:

*   freeze request handling
    
*   delay responses
    
*   reduce throughput
    

* * *

**Example Scenario**

Imagine:

*   one user requests a large file
    
*   server blocks while reading it
    

During that time:

***other incoming requests may also get delayed.***  
This is why blocking code is bad for high-traffic servers.

* * *

### Async Operations in Node.js

Node.js uses asynchronous operations to avoid blocking.

Async tasks are handled using:

*   event loop
    
*   `libuv`
    
*   thread pool  
    

Operations like:

*   file reading
    
*   API calls
    
*   database queries
    
*   timers
    

run outside the main execution flow.

When completed:

*   callbacks/promises are queued
    
*   event loop executes them later
    

* * *

**Example**

```javascript
const fs = require("fs");

fs.readFile("test.txt", "utf-8", (err, data) => {
  console.log(data);
});

console.log("reading file...");
```

Output:

```shell
reading file...
(file content later)
```

File reading happens asynchronously.

* * *

### Real-World Examples

**File Reading**

```javascript
fs.readFile("data.txt", "utf-8", callback);
```

Node.js reads the file without blocking the server.

* * *

### Database Calls

```javascript
db.findUser(id).then(user => {
  console.log(user);
});
```

Database requests take time, so they are handled asynchronously.

* * *

### API Requests

```javascript
fetch("https://api.example.com")
  .then(res => res.json())
  .then(data => console.log(data));
```

Network requests are also non-blocking.

* * *

### Why Non-Blocking is Important

Non-blocking behavior allows Node.js to:

*   handle many users efficiently
    
*   stay responsive
    
*   improve scalability
    
*   avoid wasting resources
    

This is one of the biggest reasons Node.js is popular for backend development.
