Understanding threads in computing is crucial before delving into Node.js’s single-threaded architecture. Threads are sequences of instructions executed by a processor, broadly categorized as single-threaded and multithreaded processes. Single-threaded processes execute instructions sequentially, while multithreaded processes allow simultaneous execution of instructions in different sequences, enhancing task efficiency.
Node.js, using a single-threaded approach called the Event Loop, efficiently handles multiple tasks without requiring additional threads. This design simplifies development and resource management. For tasks such as handling web requests or managing data transfers, Node.js excels due to its ability to manage numerous operations concurrently.
Before starting with NodeJS single threading, let’s first understand about process, threads and types of threads:

Process vs Threads

Process
Threads

Understanding Threads

In computing, threads are sequences of instructions that a processor executes. There are two main types: single-threaded and multithreaded processes.
Single-Threaded Process Multithreaded Process
How does it work?

Instructions

Executed sequentially, one after another.

Executed simultaneously in different sequences. This allows for more efficient handling of tasks.

E.g

For example: Instruction A ->Instruction B -> Instruction C

Instructions won't wait for others to finish unless grouped in different sequences.

Single Threading and Event Loop Architecture

Single Threaded Architecture

Description of the diagram:
  • n = Number of requests by clients to the Node.js web server.
    Let’s assume, they are accessing our Web Application built on top of Node.js
    concurrently. Clients are Client-1, Client-2 . . . Client-n.
    m = number of threads in thread pool.
  • Web Server receives Client-1, Client-2 . . . till Client-n requests and places them in the Event Queue.

NodeJS Single Threaded

Node.js follows a single-threaded model called the Event Loop. This model is inspired by JavaScript’s event-based system with callbacks. It can handle multiple client requests concurrently without creating multiple threads. This is achieved through the Event Loop, which efficiently manages tasks.

Event Loop in Node.js
  • Event Loop manages the execution of instructions in Node.js.
  • It can handle intensive I/O operations efficiently without blocking other tasks.
  • Requests are processed based on the order they arrive, ensuring smooth execution.
Blocking the Event Loop
  • Blocking the event loop prevents the execution of other instructions.
  • Intensive CPU operations can block the event loop, affecting performance.
Why Node.js Single Threading
  • Originally designed for asynchronous processing to enhance performance and scalability.
  • Single-threaded, asynchronous processing avoids complexities associated with threading.
  • Asynchronous tasks like network calls or file system operations are handled separately from the main thread.
How Node.js Serves Multiple Requests
  • Node.js maintains a task queue and utilizes callbacks to handle multiple requests concurrently
  • Tasks are not blocked, allowing for swift processing of requests.
Worker Threads in Node.js
  • While Node.js is single-threaded, it supports worker threads for parallel execution of JavaScript.
  • Worker threads are beneficial for CPU-intensive operations, freeing up the main thread for I/O tasks.
  • However, they don’t change the single-threaded architecture of Node.js.
Advantages of Node.js Single Threading
  • Can handle numerous concurrent client requests easily.
  • Reduces the need for creating multiple threads, thus, saving resources.
  • Improves performance and scalability under typical web loads. Let’s make this concept simple to understand with the diagrams below.

Event loop – Task Processing | Image Source:  Stackoverflow

Example
Case 1: Database API takes more time than the Math API : DatabaseAPI > MathAPI
Case 2: Math API takes more time than the Database API: MathAPI > DatabaseAPI

These requests arrive in different orders.

NodeJS has a single thread to handle all requests, the linear request arrives and a single thread is used to handle that request. If you want to query a database, a thread doesn’t have to wait for the database to return data while the database is executing a query, a thread will be used to serve another client request.

When the database prepares the results, it puts the message to the event queue. NodeJS continuously monitors the queue in the background. When it finds any event in this queue, it will take it out and process it. This kind of architecture makes NodeJS ideal for building an application that includes a lot of disks or network access for I/O intensive applications.

On the contrary, Node.js is not suitable for CPU-intensive applications, such as a Math API that demands extensive calculations best handled by the CPU. Node.js operates on a single thread, meaning that while processing calculations for one client, others must wait.

Here, APIs take below times to complete requests:

1. DB API taking more time compare to Math API
# API Name Description Time (In Seconds)
1
DB API
API having database relevant operations
~11.2 seconds
2
Math API
API having mathematical complex operations
~5.28 seconds
2. DB API taking less time compare to Math API
# API Name Description Time (In Seconds)
1
DB API
API having database relevant operations
~8.02 seconds
2
Math API
API having mathematical complex operations
~12.2 seconds
Let’s understand the scenario with below matrix:
Parallel Sequence
1. DB API

2. DB API
1. Math API

2. Math API
1. DB API

2. MATH API
1. MATH API

2. DB API
DB API: ~11.2 seconds

Math API: ~5.28 seconds

Total Completion Time
11.2 Seconds
10.56 Seconds
11.2 Seconds
16.48 Seconds
DB API: ~8.02 seconds
Math API: ~12.2 seconds

Total Completion Time
8.02 seconds
24.4 Seconds
12.2 Seconds
20.22 Seconds

Both API comparison for parallel and sequence order with diff. timings |  Image Source: Thecreativedev

Conclusion

  • The single-threaded architecture of Node.js, managed by the Event Loop, facilitates effective management of concurrent requests.
  • While it supports worker threads for CPU-intensive tasks, its primary strength lies in its single-threaded, asynchronous processing model.

Vaibhav Shah