What are worker threads in Node.js?
Worker Threads in Node.js
Worker Threads (introduced in Node.js 10, stable in 12) allow running JavaScript in parallel threads within the same process. Unlike the Cluster module (which creates separate processes), worker threads share memory and are designed for CPU-intensive tasks.
When to Use Worker Threads
| Use Case | Recommended |
|---|---|
| I/O operations (file, network) | ❌ Event loop handles this fine |
| Heavy computation (ML, hashing, parsing) | ✅ Worker Threads |
| Parallel HTTP servers | ❌ Use Cluster |
| Image/video processing | ✅ Worker Threads |
| Blocking synchronous libraries | ✅ Worker Threads |
Basic Example
js
// worker.js
const { workerData, parentPort } = require('worker_threads');
function heavyComputation(n) {
let result = 0;
for (let i = 0; i < n; i++) result += Math.sqrt(i);
return result;
}
const result = heavyComputation(workerData.n);
parentPort.postMessage(result); // send result backjs
// main.js
const { Worker } = require('worker_threads');
function runWorker(workerData) {
return new Promise((resolve, reject) => {
const worker = new Worker('./worker.js', { workerData });
worker.on('message', resolve);
worker.on('error', reject);
worker.on('exit', (code) => {
if (code !== 0) reject(new Error(`Worker exited with code ${code}`));
});
});
}
// Main thread is NOT blocked!
runWorker({ n: 1e9 }).then(result => {
console.log('Result:', result);
});
console.log('Main thread continues running...');Shared Memory with SharedArrayBuffer
js
// main.js
const { Worker } = require('worker_threads');
const sharedBuffer = new SharedArrayBuffer(4); // 4 bytes
const sharedArray = new Int32Array(sharedBuffer);
sharedArray[0] = 0;
const worker = new Worker(`
const { workerData } = require('worker_threads');
const shared = new Int32Array(workerData.sharedBuffer);
shared[0] = 42; // write to shared memory
`, {
eval: true,
workerData: { sharedBuffer }
});
worker.on('exit', () => {
console.log('Shared value:', sharedArray[0]); // 42
});Worker Thread Pool Pattern
For production use, create a pool to reuse workers:
js
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
const os = require('os');
class WorkerPool {
constructor(workerFile, size = os.cpus().length) {
this.workers = Array.from({ length: size }, () => ({
worker: new Worker(workerFile),
busy: false
}));
this.queue = [];
}
run(data) {
return new Promise((resolve, reject) => {
const free = this.workers.find(w => !w.busy);
if (free) {
this._execute(free, data, resolve, reject);
} else {
this.queue.push({ data, resolve, reject });
}
});
}
_execute(entry, data, resolve, reject) {
entry.busy = true;
entry.worker.postMessage(data);
entry.worker.once('message', result => {
entry.busy = false;
resolve(result);
if (this.queue.length > 0) {
const next = this.queue.shift();
this._execute(entry, next.data, next.resolve, next.reject);
}
});
entry.worker.once('error', reject);
}
}Worker Threads vs Cluster
| Worker Threads | Cluster | |
|---|---|---|
| Process | Same process | Separate processes |
| Memory | Can share (SharedArrayBuffer) | Separate memory |
| Communication | Fast (MessagePort) | Slower (IPC) |
| Best for | CPU computation | Network scaling |
| Isolation | Lower | Higher (process crash) |
Summary
Worker Threads solve the biggest limitation of Node.js: CPU-intensive tasks that would block the event loop. Use them for heavy computations — but for most I/O-bound tasks, the event loop handles concurrency perfectly without threads.
Short Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.