An introduction to Worker Threads

An introduction to Worker Threads

Worker Threads in Node.js are a way to run JavaScript in parallel on multiple tasks. They allow you to offload CPU-intensive tasks from the main thread to prevent blocking operations and keep your application responsive. In other words, workers create a parallel process and work separately from the main threads.

Why Use Worker Threads?

Node.js is primarily single-threaded when it comes to JavaScript code execution. This means that all JS logic runs on a single thread — the main thread — where the V8 engine and the event loop operate. While Node.js handles asynchronous I/O very efficiently (like reading files, making HTTP requests, or querying a database), it struggles with CPU-bound tasks such as image processing, data compression, or complex mathematical operations. These tasks block the event loop and can make your application unresponsive.

To address this limitation, Node.js introduced Worker Threads (available since v10.5.0 and stable from v12). Worker Threads allow you to run JavaScript in parallel, using multiple threads within the same Node.js process.

Unlike traditional threads in languages like Java, C++, or C#, where threads share memory and interact directly through synchronized access (e.g., using locks, semaphores, or mutexes), Worker Threads in Node.js do not share memory by default. Instead, they use a message-passing system, sending serialized data between threads using postMessage and on('message').

This design reduces the risk of bugs like race conditions and deadlocks. Still, it also means that Worker Threads in Node.js are more isolated and slightly more limited than native threading in other environments. Shared memory is only possible using special constructs like SharedArrayBuffer and Atomics.


How this works?

  • Each Worker runs in its isolated thread.
  • Workers do not share memory with the main threads (except through specific SharedArrayBuffers or transferable objects).
  • Communication between the main thread and workers is done via postMessage and on(‘message) using a message-passing model.

// Worker implementation
// This file is responsible for creating and managing worker threads

import { Worker } from "node:worker_threads";
import path from 'node:path';

export function runWorker(data: number) {
  return new Promise((resolve, reject) => {
    const workerPath = path.resolve(__dirname, 'worker.js');
    const worker = new Worker(workerPath, { workerData: data });

    worker.on('message', (result) => {
      resolve(result);
    });

    worker.on('error', (error) => {
      reject(error);
    });

    worker.on('exit', (code) => {
      if (code !== 0) {
        reject(new Error(`Worker stopped with exit code ${code}`));
      }
    });
  });
}        

  • A new thread is created by loading worker.js.
  • workerData Is the input passed to the worker (in this case, a number).
  • This launches an entirely separate thread that runs the logic defined in worker.js.
  • When the worker thread completes the task and sends a message using parentPort.postMessage(...), the main thread receives the result here and resolves the promise.

// How to implement a worker thread in Node.js
// worker.js file

import { fibonacci } from "../utils/fibonacci";
import { parentPort, workerData } from "worker_threads";


const result = fibonacci(workerData);
parentPort?.postMessage(result);        

  • Executes the Fibonacci function using the workerData input.
  • Since this is CPU-bound (especially for large numbers), running it here avoids blocking the main thread.
  • Sends the computed result back to the main thread using postMessage.
  • The parentPort?. Optional chaining ensures it doesn't crash if the port isn't available (safe but optional).


When and don’t Use Worker Threads

  • Heavy computation (CPU-bound)? R: ✅ Yes
  • Image/video/audio processing? R: ✅ Yes
  • Hashing, encryption, compression? R:✅ Yes
  • Reading files, API calls? R: ❌ No
  • Database operations? R: ❌ No
  • Real-time web servers? R: ❌ No (unless doing CPU-heavy work)

Worker Threads are a powerful tool — but like all tools, they should be used only when necessary. Most typical Node.js apps don’t need them, and instead benefit from the simplicity and performance of the single-threaded, event-driven model.

Check link of code:  https://github.com/EduardoDrozda/node-workers

#nodejs #nestjs #backend


Tássia Meira

Analista financeiro | Estudante de Contabilidade | Foco em Contabilidade e Dados | +8 anos em Finanças e Processos

3mo

💡 Ótima informação

Like
Reply

To view or add a comment, sign in

Others also viewed

Explore topics