Working with Worker Threads
1. Creating Worker Threads (new Worker)
Example
import { Worker } from "node:worker_threads";
const w = new Worker(new URL("./worker.js", import.meta.url), { workerData: { n: 42 } });
w.on("message", console.log);
2. Passing Data to Workers (workerData)
| Mechanism | Use |
|---|---|
workerData | One-time clone at start |
postMessage(data) | Ongoing messaging |
transferList | Zero-copy transfer of ArrayBuffer/MessagePort |
3. Communicating with postMessage
Example
// main
w.postMessage({ task: "hash", data: buffer }, [buffer.buffer]);
// worker
import { parentPort } from "node:worker_threads";
parentPort.on("message", (m) => parentPort.postMessage(compute(m)));
4. Handling Messages
| Event | Fires |
|---|---|
message | Data from peer |
messageerror | Deserialization failed |
online | Worker started |
exit | Worker terminated |
5. Handling Worker Errors
| Event | Detail |
|---|---|
error | Uncaught exception |
exit code != 0 | Crashed |
6. Transferring ArrayBuffers
Example: Zero-copy
const buf = new ArrayBuffer(1024 * 1024);
w.postMessage(buf, [buf]); // ownership transferred
console.log(buf.byteLength); // 0 — neutered
7. Sharing Memory (SharedArrayBuffer)
| API | Use |
|---|---|
new SharedArrayBuffer(n) | Memory shared across workers |
new Int32Array(sab) | Typed view |
| Synchronize | Use Atomics |
8. Using Atomics for Synchronization
| Method | Use |
|---|---|
Atomics.add / sub / load / store | Atomic ops |
Atomics.wait(arr, idx, val) | Block until value changes |
Atomics.notify(arr, idx, count) | Wake waiters |
Atomics.compareExchange | CAS |
9. Terminating Workers (worker.terminate)
| API | Returns |
|---|---|
await worker.terminate() | Exit code |
worker.unref() | Don't keep loop alive |
10. Using Worker Thread Pools
| Library | Use |
|---|---|
piscina | Production-grade pool |
workerpool | Simple API |
| Roll-your-own | Round-robin send to idle workers |
11. Understanding Worker vs Cluster
| Aspect | Cluster | Worker Threads |
|---|---|---|
| Memory | Separate processes | Same process, separate isolates |
| Best for | Scaling I/O across CPUs | CPU-bound tasks within one process |
| Communication | IPC + JSON | structuredClone + transferables |
| Crash isolation | Strong (one process per worker) | Weaker |
| Memory cost | Higher (full V8 per process) | Lower (~10–20 MB / worker) |