bugl
bugl
HomeLearnPatternsSearch
HomeLearnPatternsSearch

Loading lesson path

Learn/Node.js/Perfomance & Scaling
Node.js•Perfomance & Scaling

Node.js Worker Threads Module

Concept visual

Node.js Worker Threads Module

push / pop from the top({[← top

What are Worker Threads?

Worker Threads are a feature introduced in Node.js (initially in v10.5.0 as an experimental feature and stabilized in v12) that allows JavaScript code to run in parallel across multiple CPU cores. Unlike the child_process or cluster modules, which create separate Node.js processes, Worker Threads can share memory and run true parallel JavaScript code.

Formula

The Node.js Worker Threads module addresses the limitations of Node.js's single - threaded nature for CPU - intensive tasks.

While Node.js excels at I/O-bound operations thanks to its asynchronous event loop, it can struggle with CPU-bound tasks that can block the main thread and affect application performance.

Note:

Worker Threads are different from Web Workers in browsers, although they share similar concepts. Node.js Worker Threads are specifically designed for the Node.js runtime environment.

When to Use Worker Threads

Worker Threads are most useful for:

Formula

CPU - intensive operations (large calculations, data processing)

Parallel processing of data

Operations that would otherwise block the main thread

They are not necessary for:

Formula

I/O - bound operations (file system, network)

Operations that already use asynchronous APIs

Simple tasks that complete quickly

Importing the Worker Threads Module

The Worker Threads module is included in Node.js by default. You can use it by requiring it in your script:

const {

Worker, isMainThread, parentPort, workerData

} = require('worker_threads');

Key Components

Component

Description

Worker

Class for creating new worker threads isMainThread

Boolean that is true if the code is running in the main thread, false if it's running in a worker parentPort If this thread is a worker, this is a MessagePort allowing communication with the parent thread workerData

Data passed when creating the worker thread

MessageChannel

Creates a communication channel (pair of connected MessagePort objects)

MessagePort

Interface for sending messages between threads threadId

Unique identifier for the current thread

Creating Your First Worker Thread

Formula

Let's create a simple example where the main thread creates a worker to perform a CPU - intensive task:
// main.js const { Worker } = require('worker_threads');
// Function to create a new worker function runWorker(workerData) {
return new Promise((resolve, reject) => {
// Create a new worker const worker = new Worker('./worker.js', { workerData });
// Listen for messages from the worker worker.on('message', resolve);
// Listen for errors worker.on('error', reject);
// Listen for worker exit worker.on('exit', (code) => {
if (code !== 0) {
reject(new Error(`Worker stopped with exit code ${code}`));
}
});
});
}
// Run the worker async function run() {
try {
// Send data to the worker and get the result const result = await runWorker('Hello from main thread!');
console.log('Worker result:', result);
} catch (err) {
console.error('Worker error:', err);
}
}
run().catch(err => console.error(err));
// worker.js const { parentPort, workerData } = require('worker_threads');
// Receive message from the main thread console.log('Worker received:', workerData);
// Simulate CPU-intensive task function performCPUIntensiveTask() {

Formula

// Simple example: Sum up to a large number let result = 0;
for (let i = 0; i < 1_000_000; i++) {
result += i;
}
return result;
}
// Perform the task const result = performCPUIntensiveTask();
// Send the result back to the main thread parentPort.postMessage({

receivedData: workerData, calculatedSum: result

});

In this example:

The main thread creates a worker with some initial data

The worker performs a CPU-intensive calculation

The worker sends the result back to the main thread The main thread receives and processes the result

Key Concepts in the Example

The

Worker constructor takes the path to the worker script and an options object The workerData option is used to pass initial data to the worker The worker communicates back to the main thread using parentPort.postMessage() Event handlers ( message, error, exit ) are used to manage the worker lifecycle

Communication Between Threads

Worker threads communicate by passing messages. The communication is bidirectional, meaning both the main thread and workers can send and receive messages.

Previous

Node.js Cluster Module