
January 18, 2026
0
0
15
I shipped a Node API thinking it was all sunshine and rainbows, right? Traffic started climbing, and suddenly these CPU-intensive tasks showed up – image resizing, some crypto stuff, scoring models the data scientists cooked up – and my event loop just started choking; requests timing out, AWS t3.medium instances crying for help and all that good stuff. I was staring at Datadog at 3 AM, realizing I needed to actually *do* something about it. Turns out, `worker_threads` are the answer if you want real parallelism without rewriting everything in Go, but you gotta use them right.

Before you even *think* about diving into patterns, you need a solid, reusable worker. Trust me, you don't want to copy-paste that crap all over your codebase. This is the base I ended up with – it takes a function name and arguments, executes the function, and returns a result, or returns the error details. Simple. Clean. And it won't make you want to scream when debugging it at 2 AM. Here's the code I ended up using:
1// worker.js
2const { parentPort, workerData } = require('node:worker_threads');
3
4async function heavyFizzBuzz(n) {
5 let c = 0;
6 for (let i = 0; i < n; i++) c += (i % 3 === 0 || i % 5 === 0) ? 1 : 0;
7 return c;
8}
9
10const ops = { heavyFizzBuzz };
11
12(async () => {
13 try {
14 const { op, args } = workerData;
15 const result = await ops[op](...args);
16 parentPort.postMessage({ ok: true, result });
17 } catch (err) {
18 parentPort.postMessage({ ok: false, error: { message: err.message, stack: err.stack } });
19 }
20})();Need to hash a password *now*? Gotta compress a file *fast*? This is my go-to pattern for occasional, short CPU bursts that you don't want clogging up the main thread. It's fire-and-forget, but you better make sure the work actually *completes* or you will see problems down the line. I once forgot proper error handling and ended up with zombie processes eating all the memory.
1const { Worker } = require('node:worker_threads');
2
3function runHeavy(op, ...args) {
4 return new Promise((resolve, reject) => {
5 const w = new Worker(require.resolve('./worker.js'), { workerData: { op, args }});
6 w.once('message', m => m.ok ? resolve(m.result) : reject(new Error(m.error.message)));
7 w.once('error', reject);
8 w.once('exit', code => { if (code !== 0) reject(new Error(`Worker exited ${code}`)); });
9 });
10}
11
12// usage…15 views
0 shares
Trending
If you wanted to know more details please share email with us...