Offloading CPU work with worker_threads
Keeping the event loop free during CPU-bound work.
Heavy sync work blocks the single event loop and stalls all requests; move it to a Worker, message the input, await the result asynchronously, and ideally pool workers.
WHAT THIS TESTS: Whether you understand that Node runs JavaScript on one event-loop thread, that CPU-bound work starves all other requests, and how worker_threads moves that work off the main thread.
A GOOD ANSWER COVERS: The problem is that image processing is synchronous CPU work; running it in the handler blocks the single event loop, so every other request stalls until it finishes, destroying latency and throughput. worker_threads lets you run JavaScript on a separate thread within the same process. Refactor: create a worker script that performs the processing. In the handler, instantiate a Worker (or pull one from a pool), pass the input image or its path via workerData or postMessage, and return a promise that resolves when the worker posts back its result via parentPort.postMessage and rejects on its error event. The handler stays async and the event loop remains free to serve other requests while the worker crunches on another core. Because spawning a thread per request is expensive, use a worker pool (a fixed set of reusable workers, via a library like Piscina or a hand-rolled pool) so you cap concurrency to roughly the core count and reuse threads. Transfer large buffers with transferList to avoid copying.
COMMON WRONG ANSWERS: Leaving the computation inline and assuming async syntax helps (async does not parallelize CPU work); using setImmediate or process.nextTick to break it up (still on the main thread); reaching for cluster (that scales whole processes for IO concurrency, heavier and not ideal for offloading one task); spawning unbounded workers per request and exhausting resources.
LIKELY FOLLOW-UPS: When would you choose worker_threads over cluster? How does a worker pool bound resource use? How do you pass large data efficiently (SharedArrayBuffer, transferList)? How do you handle worker errors and timeouts?
ONE CONCRETE EXAMPLE: POST /resize hands the upload buffer to a pooled worker via transferList; the worker resizes the image and posts the result back; the handler awaits that message and responds. Meanwhile the event loop keeps accepting and serving other requests instead of freezing for the duration of the resize.
Read the original → nodejs.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.