Understanding Node.js: Single-Threaded Server-Side Language
Tags: node, javascript, eventloop, discuss
Published: 2020-02-07 11:47:54

Most of the server-side languages, like PHP, ASP.NET, Ruby, JAVA servers, follow multi-threaded architecture. That means, every request by the client results in the instantiation of a new thread or even a process.

However, in Node.js, all requests are handled in a single thread with shared resources. Then how does Node.js handle concurrent traffic or requests? It follows “**Single Threaded Event Loop Model**” architecture that runs on top of a single V8 engine instance.

Node.js is event-driven that implements background workers to achieve non-blocking asynchronous behavior. We called it the [**Observer Pattern**](https://en.wikipedia.org/wiki/Observer_pattern). Node thread keeps an event loop and whenever a task gets completed, it fires the corresponding event which signals the event-listener function to execute as illustrated below.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/eij3xvjtatnne3frsjn9.jpg)

As soon as Node.js starts, it initializes the event loop, processes the provided input script (i.e. initiates variables and declares functions) which may make async API calls, schedule timers, or call `process.nextTick()`, then begins processing the event loop.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/88yij04zx5gq2p7ruh68.png)

As shown in the figure above, each phase has a FIFO queue of callbacks to be executed.

**Overview of the Phases:**
**timers:**  this phase executes callbacks scheduled by  `setTimeout()`  and  `setInterval()`.

**pending callbacks**: executes I/O callbacks deferred to the next loop iteration.

**idle, prepare**: only used internally.

**poll**: retrieve new I/O events; execute I/O related callbacks (almost all with the exception of close callbacks, the ones scheduled by timers, and  `setImmediate()`); NodeJs will block here when appropriate.

**check**:  `setImmediate()`  callbacks are invoked here.

**close callbacks**: some close callbacks, e.g.  `socket.on('close', ...)`.

More detail on this can be read from the  [official docs](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/).

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/yz6hg3x6j1wa865nvbwm.png)

As shown in the above block diagram, Node.js listens and passes every concurrent traffic in a queue, which will be executed by an event loop as explained above. Let’s see an example to observe this single-threaded architecture of a Node.js web application.

```javascript
const app = express()

let visitorCount = 0

app.get("/", (req, res, next) => {
	visitorCount++

	res.send(`Hello World, visitor counter is: ${visitorCount}`)
})

const port = 8002
app.listen(port, () => {
	console.log(`Start listening at port: ${port}`)
})
```

In the above example, we are using `express-js` which we need to [install](https://expressjs.com/en/starter/installing.html) from `npm.` To run the above script, simply type the following command in your terminal.

```sh
$ node server.js         // here, server.js is the name of the file
```
Now, if we browse `localhost:8002` in the browser, on every request, the `visitorCount` gets updated. Isn't that magic? In other programming languages, to achieve this, we will need to store that counter in some persistent storage. Here, as per the output, on every request, the `visitorCount` variable is being updated. That means, for all requests, Node.js is running the same instance (thread/process) and `visitorCount` variable is the same for all the requests.

This is how Node.js works. Due to all these architectural implementations of Observer patterns, Node.js is pretty fast compared to similar other server-side languages and technologies.

> This article was originally published in [YIPL Blog](https://blog.yipl.com.np/node-js-understanding-single-threaded-server-side-language-f8e3f52c724e).