Worker Threads in Node.js: Running CPU-Heavy Work in Parallel

A
Author
07 Jul, 2026 1 min read 943 views

Node.js runs your JavaScript on a single thread. That's fine for I/O, but a CPU-heavy task (resizing images, parsing a huge file, heavy maths) blocks the event loop, and every other request waits.

Spot the problem

app.get('/report', (req, res) => {
  const result = crunchNumbers(bigDataset); // takes 3 seconds: the whole server freezes
  res.json(result);
});

Move the work to a worker

// crunch-worker.js
import { parentPort, workerData } from 'node:worker_threads';
import { crunchNumbers } from './crunch.js';

parentPort.postMessage(crunchNumbers(workerData));
// server.js
import { Worker } from 'node:worker_threads';

function runCrunch(data) {
  return new Promise((resolve, reject) => {
    const worker = new Worker(new URL('./crunch-worker.js', import.meta.url), { workerData: data });
    worker.once('message', resolve);
    worker.once('error', reject);
    worker.once('exit', (code) => code !== 0 && reject(new Error(`Worker exited with code ${code}`)));
  });
}

app.get('/report', async (req, res) => {
  res.json(await runCrunch(bigDataset)); // the event loop stays free
});

Use a pool in production

Starting a worker has a cost. A pool keeps a fixed number of workers (often one per CPU core) and queues tasks. The piscina package is a popular, well-maintained pool:

import Piscina from 'piscina';

const pool = new Piscina({ filename: new URL('./crunch-task.js', import.meta.url).href });
const result = await pool.run(bigDataset);

When not to use workers

  • For I/O (database calls, HTTP requests): async code already handles that without blocking.
  • For tiny tasks: copying data to a worker can cost more than the work itself.
  • To scale across machines: use multiple processes or containers behind a load balancer.

Use SharedArrayBuffer or transferable objects (like ArrayBuffer) to avoid copying large binary data between threads.

Was this article helpful?

Comments

No comments yet. Have a question or a tip? Be the first to share it.

Leave a comment

Comments are reviewed before they appear.