Rust vs Node.js : benchmark backend et latence réelle
Sur un banc communautaire indépendant mis à jour en août 2025, les frameworks Rust tournent tous entre 18 000 et 22 000 requêtes par seconde avec 1,4 à 1,7 ms de latence. Les frameworks Node.js équivalents plafonnent entre 5 766 et 9 340 req/s, à 3,4-5,5 ms, sur le même matériel (Sharkbench, 24 août 2025).
Nous n'avons pas fait tourner ce banc nous-mêmes : ce sont des chiffres tiers, publics, sourcés et datés. Cet article détaille ce qu'ils disent, la méthodologie derrière, et ce que ça change réellement pour un choix de backend — pas une comparaison Aurabase contre un concurrent.
Le cœur d'Aurabase tourne en Rust, sur axum et tokio — vérifié dans le Cargo.toml du monorepo, dix services partageant la même dépendance. Mais nous n'avons publié aucun chiffre de performance qui nous soit propre à ce jour. Si vous cherchez une latence Aurabase précise, elle n'existe pas encore : la méthodologie viendra avant le chiffre, pas l'inverse.
- Sur Sharkbench (banc communautaire, Ryzen 7 7800X3D, Docker/Linux, 24/08/2025) : Actix, Hyper, Axum et Rocket tournent tous entre 18 047 et 21 965 req/s à 1,4-1,7 ms. Fastify, Koa et Express plafonnent entre 5 766 et 9 340 req/s côté Node.js, à 3,4-5,5 ms.
- Le runtime pèse autant que le langage : le même code Express passe de 5 766 req/s sur Node.js à 18 917 req/s sur Bun — un facteur ×3,3 sans changer une ligne.
- L'écart de mémoire est le plus net : 8,5 Mo pour Axum contre 82,5 Mo pour Express/Node.js — cohérent avec l'absence de garbage collector de Rust.
- Aurabase n'a publié aucun benchmark qui lui soit propre à ce jour. Le cœur Rust/axum/tokio est vérifié dans le code — pas la performance.
- Un chiffre isolé ne prouve rien : matériel, version de framework, taille de payload et niveau de concurrence font varier le classement plus que le langage seul.
Ce que montre un banc tiers récent
Sharkbench est un projet communautaire indépendant qui mesure trois choses : la capacité d'un framework à traiter des requêtes HTTP concurrentes, des opérations I/O et de la sérialisation JSON. Le test tourne sous Docker/Linux sur un Ryzen 7 7800X3D, avec une dernière mise à jour publique le 24 août 2025 (sharkbench.dev/web, consulté le 24 août 2026).
Source : Sharkbench, 24 août 2025 — Docker/Linux, Ryzen 7 7800X3D.
Axum — le framework qu'utilise Aurabase pour son cœur Rust, vérifié dans Cargo.toml — traite 21 030 requêtes par seconde sur ce banc. Express, le framework Node.js le plus utilisé en production, en traite 5 766 sur le même matériel : un facteur 3,6. Ce n'est pas un cas isolé. Les quatre frameworks Rust testés se tiennent tous dans une fourchette étroite de 18 000 à 22 000 req/s, alors que les trois frameworks Node.js testés plafonnent entre 5 766 et 9 340.
En pratique, « req/s » mesure le débit sous charge concurrente soutenue — pas la vitesse d'une requête isolée sur un site à faible trafic. Pour un endpoint appelé une fois toutes les quelques secondes, la différence ne se voit jamais. Elle devient déterminante sur un endpoint chaud — un flux temps réel, une API publique à fort trafic, un job qui enchaîne des milliers d'appels — là où le nombre de requêtes traitées par cœur CPU, à matériel égal, fixe directement la facture d'infrastructure.
La latence suit le même schéma
La latence moyenne suit la même hiérarchie sur ce banc : 1,4 à 1,7 ms pour les frameworks Rust testés, contre 3,4 à 5,5 ms pour les frameworks Node.js testés.
Source : Sharkbench, 24 août 2025 — latence moyenne, pas p99.
Ce chiffre est une moyenne, pas un p99. Les pauses de garbage collector d'un runtime managé affectent surtout la queue de distribution — les requêtes les plus lentes, pas la médiane. C'est le sujet d'un article dédié de cette série : pourquoi l'absence de garbage collector change la latence p99.
Pourquoi Rust n'a pas de pause GC à payer
Rust gère la mémoire par ownership, vérifié à la compilation — pas de garbage collector qui tourne en tâche de fond et interrompt l'exécution. Le Rust Book officiel le résume ainsi : « None of the features of ownership will slow down your program while it's running » (The Rust Programming Language, doc.rust-lang.org, consulté le 24 août 2026). La mémoire est libérée dès que la variable qui la possède sort de portée — un instant connu à la compilation, pas une pause imprévisible à l'exécution.
Node.js, à l'inverse, s'exécute sur un seul thread JavaScript et délègue les opérations I/O au noyau via une boucle d'événements à plusieurs phases (timers, callbacks différés, poll, check...) — mais tout calcul synchrone sur ce thread, y compris une passe de garbage collection du moteur V8, bloque l'exécution pendant qu'il tourne (documentation officielle Node.js, nodejs.org, consultée le 24 août 2026). C'est une différence de modèle mémoire, pas un détail d'implémentation.
La vraie surprise : le runtime pèse autant que le langage
Le résultat le plus contre-intuitif du même banc ne concerne pas Rust : il concerne Node.js lui-même. Express — un seul et même code, une seule et même API — passe de 5 766 req/s sur Node.js à 18 917 req/s sur Bun, soit un facteur ×3,3, sans changer une ligne de code applicatif (Sharkbench, 24 août 2025).
Source : Sharkbench, 24 août 2025 — même code Express, trois runtimes JavaScript.
Sur Deno, ce même code Express plafonne à 6 088 req/s — proche de Node.js, loin de Bun. Le langage JavaScript est identique dans les trois cas ; c'est le runtime — son moteur JS, son implémentation d'event loop, son ramasse-miettes — qui change la donne. Comparer « Rust » à « Node.js » sans préciser le runtime, la version et le framework revient à comparer des configurations, pas des langages.
Pourquoi un seul chiffre de benchmark ne suffit jamais
TechEmpower Framework Benchmarks illustre la même idée à plus grande échelle. Son dépôt open source a été mis à jour le 24 mars 2026, et son round le plus récent (round 23) a fait l'objet d'un billet daté du 16 mars 2026 (TechEmpower, consulté le 24 août 2026). Ce projet fait tourner de nombreux types de tests sur des centaines d'implémentations, précisément parce qu'un seul test ne représente jamais un framework, encore moins un langage.
Convex, un acteur du marché des bases de données, a formulé la position la plus nette sur le sujet : refuser de participer à la « guerre des bar charts » marketing entre bases de données concurrentes, jugée trompeuse. « It's scaling theater, not scaling », écrit l'équipe (Convex, consulté le 24 août 2026). Nous partageons cette lecture : un chiffre nu, sans méthodologie publiée, ne prouve rien — ni pour un concurrent, ni pour nous.
Ce que ça change concrètement : matériel (CPU, RAM), version exacte du framework et du runtime, taille du payload JSON, niveau de concurrence et durée du test font tous varier le classement — parfois plus que le choix du langage lui-même. Un banc qui ne publie pas ces paramètres ne se reproduit pas, donc ne se vérifie pas — voir notre méthodologie complète et reproductible pour benchmarquer un backend.
Et Aurabase dans tout ça ?
Le cœur backend d'Aurabase est écrit en Rust, sur axum et tokio — vérifié dans le Cargo.toml du monorepo : dix services (aura-gateway, aura-auth, aura-db…) partagent la même dépendance workspace axum (0.8) et le même runtime tokio, en édition 2021. Le gateway qui route le trafic data plane et management plane s'appuie sur hyper en plus d'axum — le détail complet est dans notre article sur l'architecture data plane / management plane du gateway. La structure du workspace Cargo qui porte ces dix services est documentée dans notre article sur le workspace Cargo.
Ce que nous n'avons pas encore, c'est un chiffre de débit ou de latence Aurabase publié avec méthodologie et matériel documentés. C'est délibéré : nous préférons publier la méthodologie avant le chiffre plutôt que l'inverse — c'est le sujet d'un prochain article de cette série.
Pour la comparaison d'architecture complète — cœur Rust unifié chez Aurabase contre stack hétérogène Elixir/Go/TypeScript/Node documenté chez un concurrent direct — voir notre comparatif détaillé Aurabase vs Supabase. Si vous migrez déjà un projet, le guide de migration Supabase vers Aurabase couvre le schéma, les policies RLS et le SDK.
Annexe : tableau de données complet
L'ensemble des lignes citées dans cet article, telles que publiées par Sharkbench le 24 août 2025 (Docker/Linux, Ryzen 7 7800X3D).
Citer ces données : Sharkbench, « Web Framework Benchmarks », sharkbench.dev/web, dernière mise à jour le 24 août 2025.
Questions fréquentes
Ce qu'il faut retenir
Sur le banc cité ici, les frameworks Rust tournent tous dans une fourchette étroite — 18 000 à 22 000 req/s, 1,4-1,7 ms — loin devant les frameworks Node.js sur Node.js lui-même (5 766-9 340 req/s, 3,4-5,5 ms). Mais le runtime change la donne autant que le langage : Express sur Bun rattrape presque Axum sur Rust.
Si vous évaluez un backend sur la seule performance brute, exigez la méthodologie avant le chiffre : matériel, version, taille de payload, niveau de concurrence. Aurabase n'a pas encore publié ses propres chiffres ; quand ce sera le cas, la méthodologie viendra en premier.