Worker Threads: True Parallelism in Node.js
Worker threads give Node.js a separate brain for heavy lifting, letting you run CPU-intensive code without blocking the main event loop. Use them for tasks like image processing, not I/O. The footgun is assuming memory is shared; it isn't.
WHY IT EXISTS Node.js's single-threaded event loop is excellent for I/O-bound tasks but grinds to a halt during CPU-intensive work. A long-running calculation, like complex data processing, can block the entire application, making it unresponsive. Worker threads were created to solve this exact problem by enabling true, parallel execution for heavy computational tasks.
THE MENTAL MODEL Think of your main Node.js process as a busy restaurant manager handling a flood of incoming orders (I/O). When a complex, time-consuming task arrives—like de-boning a whole fish (a CPU-bound task)—the manager doesn't stop taking orders. Instead, they delegate it to a specialized chef (a worker thread) in the back kitchen. The manager and chef communicate via written notes (messages), but they work in separate spaces with their own tools (isolated memory). This keeps the front-of-house running smoothly.
HOW IT WORKS You create a new Worker by pointing it to a separate JavaScript file. This new worker runs in its own thread with its own V8 instance, event loop, and memory. The main thread and worker thread are isolated and do not share memory. Communication is handled explicitly by passing messages back and forth using worker.postMessage() and listening for the message event. For efficiency with large data, objects like ArrayBuffers can be 'transferred' instead of copied, which cedes ownership from one thread to another, avoiding the performance hit of cloning.
WHEN TO USE IT Use worker threads for CPU-bound, not I/O-bound, operations. Three key use cases: first, heavy computations like image or video processing, cryptography, or scientific modeling. Second, processing large in-memory datasets where the transformation logic would otherwise block the event loop. Third, any long-running background task that doesn't rely on frequent I/O.
WHEN NOT TO USE IT Do not use worker threads for I/O-bound tasks like making database queries or API calls. Node's main event loop is already highly optimized for this with its asynchronous, non-blocking I/O model. Using a worker for I/O adds unnecessary overhead from thread creation and message passing, making your application less efficient. They are also overkill for very short, simple computations.
ONE CANONICAL EXAMPLE A classic example is calculating a large Fibonacci number, a CPU-intensive recursive task. The main script spawns a worker and sends it the number to calculate via postMessage. The worker script receives the message, performs the long calculation without blocking the main thread, and then uses parentPort.postMessage to send the result back. The main application remains responsive to other events while the worker is busy.
Read the original → nodejs.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.