As a Node.js developer, have you ever heard of its strength in handling I/O and asynchronous tasks? That Node.js is not the best choice for applications that heavily utilize CPU power? So what is an I/O task and why is Node.js strong in I/O? Is it true that Node.js is not really good at large calculations? Let's explore together in today's article!
I/O (Input/Output) refers to the interaction of a computer or computer program with the system's disk and network. Examples of I/O activities include reading/writing data from disk, making HTTP requests, and interacting with databases. These are much slower compared to accessing RAM or performing calculations on the CPU.
We know that Node.js uses Chrome's V8 to execute JavaScript code, but the power of V8 must also concede to I/O since they do not entirely depend on CPU speed. Activities such as reading/writing to disk, accessing random access memory (RAM), and network speed... if processed on V8 will cause severe congestion due to excessive waiting time. Therefore, Node.js must find a way to leverage V8's power while still handling I/O.
Node's solution is to use libuv to handle asynchronous I/O. This is a cross-platform C library that supports asynchronous I/O based on the Event Loop.
Speaking of the processing process. The main thread, when encountering I/O tasks, offloads them to libuv; once processed, the results are returned to the main thread through the Event Loop. Thus, the main thread does not have to wait for any I/O but only processes the results of the I/O.
Node.js has the concept of workers, which are tasked with transferring I/O requests from the main thread to libuv. During this time, they do not have to do anything else and can be de-scheduled by the operating system to allow another worker to send a request. Therefore, I/O tasks transferred earlier by workers are still processed even when the event loop is not running.
The operating system has optimized file management tools, and databases are also highly optimized to handle multiple pending requests concurrently. For example, prioritizing requests when there are multiple simultaneous read/write requests to a file.
When running a Node.js application, you will have a number of thread pools dedicated to handling I/O requests. This thread group is created by libuv. The default number is 4 but can be increased up to 128 through the environment variable UV_THREADPOOL_SIZE
.
These are jobs that require high computational capability from the CPU. They can include complex calculations for encoding/decoding, image processing, video processing... Workers can also transfer these complex computational requests, schedule them, and handle them outside the main thread. However, they can only be processed when a worker is scheduled on one of the CPU cores. For example, if your CPU has 4 cores and you create 5 workers, one of those workers will not be processed while still maintaining a resource allocation for it (memory & scheduling), leading to resource waste.
To better understand how Node.js handles heavy computational tasks through Worker Threads, I recommend reading the article What are Worker Threads? Do you know when to use Worker Threads in Node.js?.
It can be seen that while the main thread offloads I/O tasks to libuv, it prevents severe congestion. In contrast, CPU-bound tasks ultimately consume processing time. The solution is to create child processes or worker threads, but how many to create depends on hardware capabilities.
The architecture model of Node.js is designed to leverage the power of V8 while still addressing I/O tasks. Node.js is perfectly suitable for I/O-centric problems. However, it does not mean that Node.js cannot handle problems centered around CPU power. To prevent blocking the main thread, create child processes or worker threads to handle them in a separate thread.
Me & the desire to "play with words"
Have you tried writing? And then failed or not satisfied? At 2coffee.dev we have had a hard time with writing. Don't be discouraged, because now we have a way to help you. Click to become a member now!
Subscribe to receive new article notifications
Comments (1)