The earlier Event Loop lesson explained why Node handles many requests on a single thread — that works well because most server work is waiting (on a file, a database, a network response), not computing. These three tools cover the cases where that single thread genuinely isn't enough.
Runs a separate operating-system process — another program entirely, not more JavaScript on the same thread.
import { exec } from 'child_process'
exec('ls -la', (err, stdout, stderr) => {
if (err) throw err
console.log(stdout)
})Unlike child_process, a worker thread runs more JavaScript, in a real OS thread separate from the main one — for CPU-intensive work (heavy computation, image processing, large data transformation) that would otherwise block the event loop for everyone.
// worker.js
import { parentPort, workerData } from 'worker_threads'
function heavyComputation(n) {
let result = 0
for (let i = 0; i < n; i++) result += i
return result
}
parentPort.postMessage(heavyComputation(workerData))// main.js
import { Worker } from 'worker_threads'
const worker = new Worker('./worker.js', { workerData: 1_000_000_000 })
worker.on('message', (result) => {
console.log('Result:', result)
})
// The main thread — and the server's ability to handle other requests —
// stays responsive while this runsWhat worker_threads actually prevents
Running heavy synchronous computation directly on the main thread (instead of a worker) blocks every request the server is handling — this is the actual failure mode "Node is single-threaded" warnings are about.
A single Node process only ever uses one CPU core. cluster forks multiple copies of the whole application — one per core — with a built-in load balancer distributing incoming requests between them.
import cluster from 'cluster'
import os from 'os'
if (cluster.isPrimary) {
const cpuCount = os.cpus().length
for (let i = 0; i < cpuCount; i++) {
cluster.fork()
}
} else {
// This code runs in each worker process — the actual server
startServer()
}| Tool | Runs | Use for |
|---|---|---|
| child_process | A separate OS process, any program | Running a shell command or external tool |
| worker_threads | More JavaScript, a separate OS thread | CPU-heavy computation that would block the event loop |
| cluster | Multiple copies of the whole app, one per CPU core | Using every core on a multi-core server for more throughput |
What most real projects actually use
Tools like PM2 (covered in this site's Hosting & Deployment course) manage clustering and process restarts automatically — worth knowing the underlying cluster module conceptually, even when a tool handles it in practice.