Node contre Bun contre Deno : les comparaisons multi-itinéraires l’emportent sur les graphiques de RPS unique
Un concours multi-path entre Node.js, Bun et Deno : le débit brut est réel, mais la familiarité des opérateurs, les permissions, la mémoire et les routes dépendantes de la base de données déterminent l’architecture.
Sources: I Rebuilt the Same API on Node.js, Bun, and Deno. The Surprising Difference Wasn’t Throughput
Le benchmark qui compte dispose de plus d’une voie d’évaluation
Les graphiques de RPS en HTTP brut donnaient l’impression que la course était terminée : Bun bien en tête, Deno derrière lui, Node encore plus loin. Les décisions architecturales nécessitent bien plus qu’une seule voie de test synthétique.
export async function handle(request: Request): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === "/health") {
return Response.json({ status: "ok" });
}
if (url.pathname.startsWith("/v1/accounts/")) {
const account = await accounts.find(url.pathname.split("/").pop()!);
if (!account) {
return Response.json({ error: "not_found" }, { status: 404 });
}
return Response.json(account);
}
return Response.json({ error: "not_found" }, { status: 404 });
}
// Bun
Bun.serve({ fetch: handle, port: 3000 });
// Deno
Deno.serve({ port: 3000 }, handle);
deno serve \
--allow-net=0.0.0.0:3000,postgres.internal,redis.internal \
--allow-env=DATABASE_URL,REDIS_URL,OTEL_EXPORTER_OTLP_ENDPOINT \
--allow-read=./config \
main.ts
Le débit brut était réel, mais il ne suffisait plus à déterminer l’architecture
Le débit est important aux limites des courbes de coût. La plupart des API métier sont limitées par les bases de données, les mécanismes d’authentification et les opérations I/O avant même d’atteindre les limites de RPS en temps de exécution.
Node était le runtime le moins intéressant, ce qui en faisait un compliment
L’attrait de l’écosystème Node, la familiarité avec ses outils d’exploitation et sa facilité de déploiement lui permettent toujours de rester la plateforme par défaut. Être ennuyeux est un avantage lorsque les périodes de disponibilité sont limitées.
Bun était le plus rapide lorsqu’on lui laissait être Bun
Bun se distingue par ses propres API et outils. Forcer une compatibilité avec Node affaiblit cet avantage ; il convient d’évaluer honnêtement les hypothèses basées sur l’approche native de Bun.
Deno a intégré les permissions et la télémétrie dans la conception des applications
Le modèle de permissions et la bibliothèque standard de Deno placent la sécurité et l’observabilité au cœur du fonctionnement en temps réel, et non simplement comme éléments secondaires après l’implémentation du middleware.
C’est en matière de mémoire que les différences s’estompent
L’allocation de mémoire, le nettoyage automatique et l’espace utilisé en mémoire vive avec des charges réalistes sont plus importants que le nombre maximal de requêtes par seconde. Ceux qui échouent en matière de gestion mémoire deviennent également des perdants en termes de coûts dans les conteneurs.
La simplicité d’exploitation dépend de ce que l’on possède déjà
Si l’organisation utilise déjà Node sur Kubernetes avec des tableaux de bord matures, changer de runtime représente un fardeau pour tout le monde. Dans le cas d’un projet nouveau ou axé sur les environnements edge, Bun et Deno méritent d’être comparés à l’aide de benchmarks multi-route : API JSON, données multipart, WebSocket et gestionnaires liés aux bases de données.
Conclusion
Reconstruisez la même API sur différents environnements de exécution afin d’analyser les compromis — et non pour désigner un gagnant définitif à partir d’un simple test de saturation HTTP. Choisissez l’environnement qui correspond aux besoins opérationnels, aux permissions et au goulot d’étranglement réel que vous rencontrez.
Publiez le outil de benchmark accompagné des conclusions de l’article. Les captures d’écran montrant des RPS irréproducibles ne doivent pas guider la stratégie de plateforme.
Incluez dans l’évaluation le temps de démarrage initial ainsi que les performances via la ligne de commande pour les fonctions/edge, et pas seulement les RPS en état stationnaire.
Surveillez les contraintes de compatibilité : les modules natifs, les imports Node et les bibliothèques de test qui reposent sur les variables globales de Node.
Pour chaque environnement de exécution, documentez le modèle de processus en production (cluster, superviseur, isolation) que vous utiliseriez réellement.
Évaluez le coût en jours d’ingénieur ; une amélioration des RPS de 4 fois qui nécessite une réécriture des mécanismes d’authentification et du processus CI n’est pas une amélioration de performance gratuite.
Si vous utilisez réellement plusieurs environnements, maintenez un canari de compatibilité qui exécute les vingt routes les plus fréquentes sur chaque environnement de déploiement chaque nuit.
Publiez l’outil d’évaluation ainsi que les conclusions de l’article. Les captures d’écran de RPS non reproductibles ne doivent pas guider la stratégie de plateforme.
Incluez dans le tableau de scores les temps de démarrage initial et les performances via la ligne de commande pour les fonctions/edge, et pas seulement le RPS en état stationnaire.
Surveillez les problèmes de compatibilité liés aux modules natifs, aux imports Node, ainsi qu’aux bibliothèques de test qui reposent sur les variables globales de Node.
Pour chaque environnement de déploiement, documentez le modèle de processus en production (cluster, superviseur, isolation) que vous utiliserez réellement.
Évaluez le coût en jours d’ingénieur : une amélioration de 4× du RPS qui nécessite une réécriture des mécanismes d’authentification et du processus CI n’est pas une amélioration gratuite en termes de performances.
Si vous utilisez réellement plusieurs environnements, maintenez un canari de compatibilité qui exécute les vingt routes les plus fréquentes sur chaque environnement de déploiement chaque nuit.
Publiez l’outil de benchmark accompagné des conclusions de l’article. Les captures d’écran d’RPS irréproducibles ne doivent pas guider la stratégie de la plateforme.
Incluez les tests de démarrage en froid ainsi que ceux liés à l’interface ligne de commande pour les fonctions/edge, et pas seulement les mesures d’RPS en état stationnaire.
Surveillez les contraintes de compatibilité : les add-ons natifs, les imports Node, ainsi que les bibliothèques de test qui reposent sur les variables globales de Node.
Pour chaque environnement d’exécution, documentez le modèle de processus en production (cluster, superviseur, isolation) que vous utiliserez réellement.
Évaluez le coût en jours d’ingénieur : une amélioration de l’RPS quatre fois supérieure qui nécessite une réécriture des modules d’authentification et du processus CI n’est pas une amélioration gratuite en termes de performance.
Maintenez un outil de test de compatibilité qui exécute les vingt routes les plus fréquentes sur chaque environnement d’exécution chaque nuit, si vous utilisez vraiment plusieurs plateformes.
Publiez l’outil de benchmark accompagné des conclusions de l’article. Les captures d’écran d’RPS irréproducibles ne doivent pas guider la stratégie de la plateforme.
Incluez le démarrage en froid et l’expérience CLI dans le tableau de bord des fonctionnalités/edge, et non seulement le RPS en état stationnaire.
Surveillez les contraintes de compatibilité : les add-ons natifs, les imports Node, ainsi que les bibliothèques de test qui reposent sur les variables globales de Node.
Pour chaque environnement d’exécution, documentez le modèle de processus en production (cluster, superviseur, isolation) que vous utiliserez réellement.
Évaluez le coût en jours d’ingénieur ; une amélioration du RPS de 4 fois qui nécessite une réécriture des modules d’authentification et du CI n’est pas un gain de performance gratuit.
Maintenez un outil de test de compatibilité qui exécute les vingt routes principales sur chaque environnement d’exécution chaque nuit si vous utilisez réellement plusieurs plateformes.
Publiez l’outil de benchmark accompagné des conclusions de l’article. Les captures d’écran du RPS impossibles à reproduire ne doivent pas guider la stratégie de plateforme.
Incluez le démarrage en froid et l’expérience CLI dans le tableau de bord des fonctionnalités/edge, et non seulement le RPS en état stationnaire.
Surveillez les contraintes de compatibilité liées aux outils : les modules natifs, les imports Node, ainsi que les bibliothèques de test qui reposent sur les variables globales de Node.
Pour chaque environnement d’exécution, documentez le modèle de processus de production (cluster, supervisor, isolation) que vous utiliserez réellement.
Évaluez le coût en jours d’ingénieur ; une amélioration de 4 fois du RPS qui nécessite une réécriture des mécanismes d’authentification et du processus CI n’est pas une amélioration de performance gratuite.
Maintenez un outil de vérification de compatibilité qui exécute les vingt routes les plus fréquentées sur chaque environnement d’exécution chaque nuit si vous utilisez réellement plusieurs plateformes.
Publiez l’outil de benchmark accompagné des conclusions de l’article. Les captures d’écran du RPS impossibles à reproduire ne doivent pas guider la stratégie de plateforme.
Incluez dans l’évaluation le temps de démarrage et l’expérience utilisateur via la ligne de commande pour les fonctions/edge, et non seulement le RPS en état stationnaire.
Surveillez les contraintes de compatibilité liées aux outils : les modules natifs, les imports Node, ainsi que les bibliothèques de test qui reposent sur les variables globales de Node.
Pour chaque environnement de exécution, documentez le modèle de processus en production (cluster, superviseur, isolations) que vous mettriez réellement en œuvre.
Évaluez le coût en jours d’ingénieur ; une amélioration de 4× du RPS qui nécessite une réécriture des mécanismes d’authentification et du pipeline CI n’est pas une amélioration de performance gratuite.
Si vous utilisez réellement plusieurs environnements, conservez un outil de test de compatibilité qui exécute les vingt routes les plus fréquentes chaque nuit dans chacun de ces environnements.
Publiez l’outil d’évaluation des performances accompagné des conclusions de l’article. Les captures d’écran du RPS impossibles à reproduire ne doivent pas guider la stratégie de plateforme.
Incluez dans le tableau d’évaluation le temps de démarrage initial ainsi que les performances via la ligne de commande pour les fonctions/edge, et non seulement le RPS en état stationnaire.
Surveillez les contraintes de compatibilité : les modules natifs, les imports Node, ainsi que les bibliothèques de test qui reposent sur les variables globales de Node.
Pour chaque environnement de exécution, documentez le modèle de processus en production (cluster, superviseur, isolations) que vous mettriez réellement en œuvre.
Évaluez le coût de la compétition en jours d’ingénieur ; une amélioration de 4× du RPS qui nécessite une réécriture des mécanismes d’authentification et du CI n’est pas une amélioration de performance gratuite.
Si vous utilisez réellement plusieurs environnements, maintenez un outil de test de compatibilité qui exécute les vingt routes les plus fréquentes chaque nuit lors de chaque exécution.
Publiez l’outil d’évaluation ainsi que les conclusions de l’article. Les captures d’écran du RPS impossibles à reproduire ne doivent pas guider la stratégie de plateforme.
Incluez dans le tableau de score les temps de démarrage initial et les performances via la ligne de commande pour les fonctions/edge, et non seulement le RPS en état stationnaire.
Surveillez les contraintes de compatibilité : les modules natifs, les imports Node, ainsi que les bibliothèques de test qui reposent sur les variables globales de Node.
Pour chaque environnement d’exécution, documentez le modèle de processus en production (cluster, superviseur, isolation) que vous utiliserez réellement.
Évaluez le coût de la compétition en jours d’ingénieur ; une amélioration de 4× du RPS qui nécessite une réécriture des mécanismes d’authentification et du CI n’est pas une amélioration de performance gratuite.
Tenez un « canari de compatibilité » qui exécute les vingt principales routes chaque nuit lors de chaque exécution, si vous utilisez réellement plusieurs environnements.
Publiez l’outil de benchmark accompagné des conclusions de l’article. Les captures d’écran d’RPS non reproductibles ne doivent pas influencer la stratégie de plateforme.
Incluez les temps de démarrage en mode froid ainsi que les performances via la ligne de commande dans le tableau de scores pour les fonctions et les points d’edge, et non seulement les valeurs d’RPS en état stationnaire.
Les benchmarks multi-routes doivent prendre en compte les requêtes JSON POST authentifiées, les limites de téléchargement de fichiers, ainsi que des scénarios complexes avec ORM — c’est là que les exécutions diffèrent après les requêtes GET de base.
Les graphiques représentant les compétences de l’équipe sont importants : une victoire avec Bun qui laisse la moitié du personnel sans outils de test familiers revient à un arrêt de service différé.
Faites attention aux stacks TLS et HTTP/2 ; les microbenchmarks sur HTTP pur omettent les coûts liés à la terminaison des requêtes au niveau du réseau.
La taille des images de conteneur et les résultats des scans CVE varient en fonction des images de base utilisées par chaque exécution — les équipes opérationnelles tiendront compte de ces facteurs en plus des valeurs d’RPS.
Les tests de contrat contre OpenAPI garantissent l’équité des comparaisons lorsque les gestionnaires changent de port.
Enregistrez la latence p99 en conditions de charge, et non seulement le RPS médian ; les planificateurs masquent des comportements différents selon les cas d’usage.
Si vous adoptez les permissions de Deno, traduisez chaque autorisation en un document de décision architecturale afin que les services futurs ne élargissent pas silencieusement le sandbox.
La couche de compatibilité npm de Bun nécessite une liste explicite d’éléments à autoriser ou à interdire, indiquant les packages qui ne doivent pas être exécutés en production.
Node reste la référence de compatibilité : mesurez les autres solutions en fonction des écarts par rapport à Node sur vos routes réelles.
Revisez cette décision tous les trimestres ; les indicateurs de performance évoluent, tout comme vos goulots d’étranglement.
Les benchmarks multi-routes doivent inclure des requêtes JSON POST authentifiées, des limites pour le téléchargement de fichiers, ainsi qu’un scénario avec un ORM interactif — des cas où les performances diffèrent après des requêtes GET de base.
Les graphiques des compétences d’équipe sont importants : une victoire obtenue avec Bun qui force la moitié du personnel à utiliser des outils de test inconnus constitue une panne différée.
Surveillez les stacks TLS et HTTP/2 ; les micro-benchmarks sur du HTTP pur omettent les coûts liés à la terminaison au niveau du réseau.
La taille des images de conteneur et les résultats des scans CVE varient en fonction des images de base utilisées — les équipes opérationnelles tiendront compte de cela en plus du RPS.
Les tests basés sur OpenAPI garantissent une évaluation honnête lorsque les gestionnaires de requêtes changent de port.
Enregistrez la latence p99 en conditions de concurrence, et non seulement le RPS médian ; les planificateurs masquent des comportements différents en fin de distribution.
Si vous adoptez les permissions de Deno, traduisez chaque autorisation en un document de décision architecturale afin que les services futurs ne élargissent pas silencieusement le sandbox.
La couche de compatibilité npm de Bun nécessite une liste explicite d’éléments à autoriser ou à interdire, indiquant les packages qui ne seront pas exécutés en production.
Node reste la référence de compatibilité : mesurez les autres solutions en fonction des écarts par rapport à Node sur vos routes réelles.
Revoyez cette décision tous les trois mois ; les tableaux de bord relatifs aux performances en temps réel évoluent, tout comme vos goulots d’étranglement.
Les tests de comparaison sur plusieurs routes doivent inclure des requêtes JSON POST authentifiées, les limites de téléchargement de fichiers, ainsi qu’un parcours avec un ORM interactif — des éléments où les performances diffèrent après des requêtes GET de type « hello-world ».
Les graphiques représentant les compétences de l’équipe sont importants : une victoire avec Bun qui oblige la moitié du personnel à utiliser des outils de test inconnus revient à un arrêt de service différé.
Faites attention aux stacks TLS et HTTP/2 ; les microtests sur du HTTP pur omettent les coûts liés à la terminaison des requêtes au niveau du réseau.
La taille des images de conteneur et les résultats des scans CVE varient en fonction des images de base utilisées — les équipes opérationnelles prendront cela en compte en même temps que le RPS.
Les tests de contrat basés sur OpenAPI garantissent une évaluation honnête lorsque les gestionnaires de requêtes changent de port.
Enregistrez la latence p99 en situation de concurrence, et non seulement le RPS médian ; les planificateurs masquent des comportements différents pour les extrémités des données.
Si vous adoptez les permissions de Deno, traduisez chaque autorisation en un document de décision architecturale afin que les services futurs ne élargissent pas silencieusement le sandbox.
La couche de compatibilité npm de Bun nécessite une liste explicite d’éléments à autoriser ou à interdire, indiquant les paquets qui ne seront pas exécutés en production.
Node reste la référence de compatibilité : mesurez les autres solutions en fonction des écarts par rapport à Node sur vos routes réelles.