Node.js Event Loop : pourquoi votre API ralentit sous charge
Comment le blocage de l’Event Loop monothread de Node.js transforme des APIs concurrentes en goulets d’étranglement, et quelles solutions les équipes utilisent réellement en production.
Node.js est réputé pour sa capacité à gérer des milliers de connexions concurrentes avec très peu d’overhead. Pourtant, de nombreuses équipes finissent par atteindre un point où leurs APIs deviennent mystérieusement lentes sous charge. Dans la plupart des cas, la cause est une mauvaise compréhension de l’Event Loop à thread unique.
Comme Node.js gère la concurrence de manière asynchrone, les opérations d’I/O comme les requêtes base de données ou réseau peuvent être déléguées pendant que le runtime continue d’avancer. Une fois terminées, leurs callbacks sont mis en file pour être exécutés par l’Event Loop.
Le problème commence quand du travail intensif en CPU arrive sur le thread principal. Du parsing JSON complexe, du hashing lourd, de la compression ou de gros tris en mémoire peuvent bloquer complètement la boucle. Si une seule tâche prend 500 millisecondes, toutes les autres requêtes attendent derrière.
C’est pourquoi une API Node.js peut sembler saine en développement et pourtant échouer sous trafic réel. Quelques opérations bloquantes suffisent à provoquer des pics de latence visibles, des requêtes bloquées et des timeouts sur des endpoints pourtant non liés.
La première solution consiste à déporter les calculs coûteux. Les worker threads sont l’outil adapté pour les tâches CPU-bound, car ils laissent l’Event Loop principal libre de continuer à servir le trafic réseau.
Si un gros volume de données doit être traité sur le thread principal, il faut découper le travail en petits blocs avec des outils comme setImmediate afin de rendre la main entre les étapes. Combiné à une mesure du lag de l’Event Loop en production, cela permet de détecter beaucoup plus tôt les opérations bloquantes avant qu’elles n’impactent les utilisateurs.

