Node.js Event Loop: por qué tu API se ralentiza bajo carga
Cómo bloquear el Event Loop monohilo de Node.js convierte APIs concurrentes en cuellos de botella, y cuáles son las soluciones prácticas usadas en producción.
Node.js es conocido por su capacidad para manejar miles de conexiones concurrentes con una sobrecarga mínima. Sin embargo, muchos equipos de ingeniería terminan encontrando un punto en el que sus APIs se vuelven misteriosamente lentas bajo carga. En la mayoría de los casos, la causa es una mala comprensión del Event Loop de un solo hilo.
Como Node.js maneja la concurrencia de forma asíncrona, el trabajo de I/O, como consultas a base de datos o peticiones de red, puede delegarse mientras el runtime sigue avanzando. Cuando esas operaciones terminan, sus callbacks se encolan para que el Event Loop los ejecute.
El problema empieza cuando el trabajo intensivo en CPU cae en el hilo principal. Parseos complejos de JSON, hashing pesado, compresión o grandes ordenamientos en memoria pueden bloquear completamente el loop. Si una sola tarea tarda 500 milisegundos, todas las demás peticiones quedan esperando detrás.
Por eso una API Node.js puede parecer saludable en desarrollo y aun así fallar bajo tráfico real. Unas pocas operaciones bloqueantes bastan para provocar picos visibles de latencia, solicitudes colgadas y timeouts en endpoints que no tienen relación entre sí.
La primera solución es descargar el cómputo costoso. Los worker threads son la herramienta adecuada para tareas CPU-bound porque mantienen libre el Event Loop principal para seguir atendiendo tráfico de red.
Si un gran conjunto de datos debe procesarse en el hilo principal, conviene dividir el trabajo en pequeños bloques con herramientas como setImmediate para ceder control entre pasos. Si además se monitoriza el lag del Event Loop en producción, resulta mucho más fácil detectar operaciones bloqueantes antes de que impacten a los usuarios.

