Los worker threads permiten que Node ejecute JavaScript en hilos separados con verdadero paralelismo — resolviendo la mayor limitación de Node: el trabajo intensivo en CPU que bloquea el único hilo principal (y por lo tanto todas las solicitudes). Úsalos para cómputo pesado, no para I/O (que el event loop ya maneja de forma eficiente).
El problema que resuelven
// ❌ este trabajo intensivo en CPU BLOQUEA el event loop → todas las solicitudes se congelan durante su ejecución
app.get("/hash", (req, res) => {
const result = expensiveComputation(); // p. ej. crypto pesado, procesamiento de imágenes
res.json(result); // mientras tanto, ninguna otra solicitud puede ser atendida
});
Node ejecuta tu JS en un solo hilo. Un cómputo síncrono prolongado bloquea todo — el event loop no puede procesar otras solicitudes hasta que termine. Los worker threads mueven ese trabajo fuera del hilo principal.
Usar un worker thread
// main.js
import { Worker } from "worker_threads";
function runHeavyTask(data) {
return new Promise((resolve, reject) => {
const worker = new Worker("./worker.js", { workerData: data }); // se ejecuta en un NUEVO hilo
worker.on("message", resolve); // recibe el resultado
worker.on("error", reject);
worker.on("exit", (code) => { if (code !== 0) reject(new Error(`exit ${code}`)); });
});
}
// el hilo principal queda libre para atender otras solicitudes mientras esto se ejecuta
const result = await runHeavyTask({ numbers: [...] });
// worker.js — se ejecuta en paralelo, en su propio hilo
import { workerData, parentPort } from "worker_threads";
const result = expensiveComputation(workerData); // no bloquea el hilo principal
parentPort.postMessage(result); // envía el resultado de vuelta
El worker se ejecuta de forma independiente; el hilo principal sigue atendiendo solicitudes y obtiene el resultado mediante un mensaje cuando termina.
Cuándo usarlos (y cuándo no)
✓ ÚSALOS para trabajo intensivo en CPU: procesamiento de imágenes/video, cifrado, compresión,
análisis de grandes volúmenes de datos, cálculos complejos, inferencia de ML
✗ NO los uses para I/O (BD, archivos, HTTP) — el event loop asíncrono ya maneja
eso de forma eficiente; un worker agregaría sobrecarga sin ningún beneficio
La regla: workers para trabajo intensivo en CPU, el event loop para trabajo intensivo en I/O.
Worker threads vs child_process vs cluster
worker_threads → comparten memoria (paso de datos eficiente), hilos dentro del proceso — trabajo de CPU
child_process → procesos de SO separados, ejecutan otros programas — aislamiento más pesado
cluster → bifurca todo el servidor entre CPUs — escala el manejo de solicitudes
Por qué es importante
Los worker threads abordan la debilidad central de Node — las tareas intensivas en CPU que bloquean el event loop de un solo hilo y congelan todas las solicitudes concurrentes.
Saber descargar el cómputo pesado a un worker (manteniendo el hilo principal receptivo), y, crucialmente, cuándo usarlos (solo trabajo intensivo en CPU, nunca para I/O), es lo que permite a un servicio Node manejar procesamiento pesado ocasional sin sacrificar la concurrencia que hace valioso a Node.
Para agrupar workers en producción, bibliotecas como Piscina administran un pool de hilos de forma eficiente.
