PRODSovereign European BaaS platformOpen Dashboard →

Performance · 12 min read

Rust vs Node.js: backend benchmark and latency

Affane Daylami · Fondateur · July 5, 2026

Back to blog

On an independent community bench updated in August 2025, Rust frameworks all run between 18,000 and 22,000 requests per second with 1.4 to 1.7 ms of latency. Equivalent Node.js frameworks cap between 5,766 and 9,340 req/s, at 3.4-5.5 ms, on the same hardware (Sharkbench, August 24, 2025).

This English text was generated automatically from the French original and has not been reviewed yet.

We did not run this bench ourselves: these are third-party figures, public, sourced and dated. This article details what they say, the methodology behind it, and what it actually changes for a backend choice — not a comparison of Aurabase versus a competitor.

The core of Aurabase runs in Rust, on axum and tokio — verified in the Cargo.toml of the monorepo, ten services sharing the same dependency. But we have not published any performance figures of our own to date. If you're looking for precise Aurabase latency, it doesn't exist yet: the methodology will come before the number, not the other way around.

The essentials

  • On Sharkbench (community bench, Ryzen 7 7800X3D, Docker/Linux, 08/24/2025): Actix, Hyper, Axum and Rocket are all running between 18,047 and 21,965 req/s at 1.4-1.7 ms. Fastify, Koa and Express cap between 5,766 and 9,340 req/s on the Node.js side, at 3.4-5.5 ms.
  • The runtime weighs as much as the language: the same Express code goes from 5,766 req/s on Node.js to 18,917 req/s on Bun — a factor ×3.3 without changing a line.
  • The memory gap is the clearest: 8.5 MB for Axum versus 82.5 MB for Express/Node.js — consistent with the absence of Rust's garbage collector.
  • Aurabase has not published any benchmarks of its own to date. The Rust/axum/tokio core is checked in code — not performance.
  • An isolated figure proves nothing: hardware, framework version, payload size and level of competition vary the ranking more than the language alone.
#
The bench

What a recent third-party bench shows

Sharkbench is an independent community project that measures three things: a framework's ability to handle concurrent HTTP requests, I/O operations, and JSON serialization. The test runs under Docker/Linux on a Ryzen 7 7800X3D, with a last public update on August 24, 2025 (sharkbench.dev/web, accessed August 24, 2026).

Throughput in requests per second, Rust vs Node.jsActix (Rust) 21,965 req/s, Hyper (Rust) 21,781 req/s, Axum (Rust) 21,030 req/s, Rocket (Rust) 18,047 req/s, Fastify (Node.js) 9,340 req/s, Koa (Node.js) 8,828 req/s, Express (Node.js) 5,766 requests/s. Source: Sharkbench, August 24, 2025.05k10k15k20kActix (Rust)21 965Hyper (Rust)21 781Axum (Rust)21 030Rocket (Rust)18 047Fastify (Node.js)9 340Koa (Node.js)8 828Express (Node.js)5 766

Source: Sharkbench, August 24, 2025 — Docker/Linux, Ryzen 7 7800X3D.

Axum — the framework Aurabase uses for its Rust core, verified in Cargo.toml — processes 21,030 requests per second on this bench. Express, the Node.js framework most used in production, processes 5,766 on the same hardware: a factor of 3.6. This is not an isolated case. The four Rust frameworks tested all fall within a narrow range of 18,000 to 22,000 req/s, while the three Node.js frameworks tested cap out between 5,766 and 9,340.

In practice, “req/s” measures throughput under sustained concurrent load — not the speed of an isolated request on a low-traffic site. For an endpoint called once every few seconds, the difference is never seen. It becomes decisive on a hot endpoint — a real-time flow, a public API with heavy traffic, a job that strings together thousands of calls — where the number of requests processed per CPU core, for equal hardware, directly sets the infrastructure bill.

#
Latency

Latency follows the same pattern

The average latency follows the same hierarchy on this bench: 1.4 to 1.7 ms for the Rust frameworks tested, compared to 3.4 to 5.5 ms for the Node.js frameworks tested.

Average latency in milliseconds, Rust vs Node.jsActix (Rust) 1.4ms, Hyper (Rust) 1.5ms, Axum (Rust) 1.6ms, Rocket (Rust) 1.7ms, Fastify (Node.js) 3.4ms, Koa (Node.js) 3.6ms, Express (Node.js) 5.5ms. Source: Sharkbench, August 24, 2025.0ms1ms2ms3ms4ms5msActix (Rust)1.4msHyper (Rust)1.5msAxum (Rust)1.6msRocket (Rust)1.7msFastify (Node.js)3.4msKoa (Node.js)3.6msExpress (Node.js)5.5ms

Source: Sharkbench, August 24, 2025 — medium latency, not p99.

This figure is an average, not a p99. Garbage pauses in a managed runtime mostly affect the dispatch queue — the slowest requests, not the median. This is the subject of a dedicated article in this series: why the absence of garbage collector changes p99 latency.

#
Why

Why Rust doesn't have a GC break to pay

Rust manages memory by ownership, checked at compile time — no garbage collector running in the background and interrupting execution. The official Rust Book summarizes it as follows: “None of the features of ownership will slow down your program while it's running” (The Rust Programming Language, doc.rust-lang.org, accessed August 24, 2026). Memory is freed as soon as the variable that owns it goes out of scope — a known time at compile time, not an unpredictable pause at runtime.

ownership.rsrust
fn main() {
    let data = String::from("réponse API"); // `data` owns the string
    process(data); // possession leaves here
    // `data` is no longer valid here — no dangling pointer, no double free
} // `data` is released here, deterministically

fn process(s: String) {
    println!("{s}");
} // `s` goes out of scope here: immediate release, without garbage collection pass

Node.js, conversely, runs on a single JavaScript thread and delegates I/O operations to the kernel via a multi-phase event loop (timers, deferred callbacks, poll, check...) — but any synchronous computation on that thread, including a garbage collection pass from the V8 engine, blocks execution while it runs (official Node.js documentation, nodejs.org, accessed August 24, 2026). This is a memory model difference, not an implementation detail.

#
The nuance

The real surprise: the runtime weighs as much as the language

The most counterintuitive result from the same bench does not concern Rust: it concerns Node.js itself. Express — one and the same code, one and the same API — goes from 5,766 req/s on Node.js to 18,917 req/s on Bun, a factor of ×3.3, without changing a line of application code (Sharkbench, August 24, 2025).

Express throughput according to JavaScript runtime, compared to AxumAxum on Rust: 21,030 req/s. Express on Bun: 18,917 req/s. Express on Deno: 6,088 req/s. Express on Node.js: 5,766 req/s. Same Express code in all three cases. Source: Sharkbench, August 24, 2025.05k10k15k20kAxum (Rust, reference)21 030Express on Bun18 917Express on Deno6 088Express on Node.js5 766

Source: Sharkbench, August 24, 2025 — same Express code, three JavaScript runtimes.

On Deno, this same Express code caps at 6,088 req/s — close to Node.js, far from Bun. The JavaScript language is identical in all three cases; It’s the runtime — its JS engine, its event loop implementation, its garbage collection — that changes the game. Comparing “Rust” to “Node.js” without specifying the runtime, version and framework is like comparing configurations, not languages.

And Go in all this?

On this same bench, the Go Gin framework peaks at 3,546 req/s when FastHTTP — still in Go — climbs to 5,567 req/s with a latency of only 0.7 ms (Sharkbench, August 24, 2025). Two very different results for a single language: an isolated figure never summarizes an entire ecosystem.

#
Methodology

Why a single benchmark number is never enough

TechEmpower Framework Benchmarks illustrates the same idea on a larger scale. Its open source repository was updated on March 24, 2026, and its most recent round (round 23) was the subject of a post dated March 16, 2026 (TechEmpower, accessed August 24, 2026). This project runs many types of tests on hundreds of implementations, precisely because a single test never represents a framework, let alone a language.

Convex, a player in the database market, has formulated the clearest position on the subject: refusing to participate in the marketing “bar chart war” between competing databases, deemed misleading. “It's scaling theater, not scaling”, writes the team (Convex, accessed August 24, 2026). We share this reading: a bare figure, without a published methodology, proves nothing — neither for a competitor, nor for us.

What it changes in concrete terms: hardware (CPU, RAM), exact version of the framework and runtime, size of the JSON payload, level of competition and duration of the test all vary the ranking — sometimes more than the choice of language itself. A bench that does not publish these parameters does not reproduce, therefore does not verify itself — see our complete and reproducible methodology for benchmarking abackend.

#
Aurabase

And Aurabase in all this?

The core backend of Aurabase is written in Rust, on axum and tokio — checked in the Cargo.toml of the monorepo: ten services (aura-gateway, aura-auth, aura-db…) share the same workspace dependency axum (0.8) and the same runtime tokio, in 2021 edition. The gateway which routes data plane and management plane traffic relies on hyper in addition to axum — the full details are in our article on the data plane / management plane architecture of the gateway. The structure of the Cargo workspace that supports these ten services is documented in our article on the Cargo workspace.

What we don't have yet is a published Aurabase throughput or latency figure with documented methodology and hardware. This is deliberate: we prefer to publish the methodology before the figure rather than the other way around — this is the subject of a future article in this series.

For the complete architecture comparison — unified Rust core at Aurabase versus heterogeneous stack Elixir/Go/TypeScript/Node documented at a direct competitor — see our detailed comparison Aurabase vs Supabase. If you are already migrating a project, the Supabase to Aurabase migration guide covers the schema, RLS policies and SDK.

#
Data

Appendix: complete data table

All lines cited in this article, as published by Sharkbench on August 24, 2025 (Docker/Linux, Ryzen 7 7800X3D).

FrameworkRuntimeRequest/sLatencyMemory
ActixRust21 9651.4ms16.6 MB
HyperRust21 7811.5ms8.6 MB
AxumRust21 0301.6ms8.5 MB
RocketRust18 0471.7ms6.4 MB
FastifyNode.js9 3403.4ms57.0 MB
KoaNode.js8 8283.6ms53.3 MB
ExpressNode.js5 7665.5ms82.5 MB
ExpressBun18 9171.3ms53.3 MB
ExpressDeno6 0885.0ms130.7 MB
GinGo3 5461.0ms16.7 MB
FastHTTPGo5 5670.7ms13.4 MB

Cite this data: Sharkbench, “Web Framework Benchmarks,” sharkbench.dev/web, last updated August 24, 2025.

#
FAQs

Frequently asked questions

Does this mean Node.js is a bad choice?+
No. Node.js remains a solid choice for many backends, especially when the team is already proficient in TypeScript and the load is not dominated by CPU computing. The gap measured here is in raw throughput and latency under high competition — not in development productivity or the package ecosystem. On Bun, the gap with Rust is reduced significantly (18,917 req/s for Express compared to 21,030 for Axum): the choice of runtime matters as much as the choice of language.
Why is Express so slow compared to other Node.js frameworks?+
On this bench, Express (5,766 req/s on Node.js) is the slowest of the Node.js frameworks tested, behind Koa (8,828) and Fastify (9,340). Express dates from 2010 and its design favors the simplicity of the middleware rather than raw throughput. At the same runtime, the choice of framework already makes a gap of ×1.6 between Express and Fastify (Sharkbench, August 24, 2025).
How was this benchmark achieved, and can we reproduce it?+
The bench cited in this article comes from Sharkbench, an independent community project that tests concurrent HTTP requests, I/O, and JSON serialization under Docker/Linux, on a Ryzen 7 7800X3D, with a final public update on August 24, 2025 (sharkbench.dev/web). This is not an Aurabase bench — we have neither run nor validated it ourselves; we cite him because his methodology and materials are published, unlike many marketing figures.
Has Aurabase published its own benchmarks?+
No, not to date. Aurabase's Rust/axum/tokio core is verified in the monorepo source code, but no Aurabase-specific throughput or latency figures have been measured and published. This article compares Rust and Node.js in general, based on third-party sourced benches — this is not a comparison of Aurabase against a competitor.
A difference in throughput and memory, what difference does it make to the infrastructure bill?+
On the cited bench, Axum consumes 8.5 MB of memory compared to 82.5 MB for Express on Node.js — a factor close to ×10 (Sharkbench, August 24, 2025). Less memory per instance and more requests processed per CPU core make it possible, for equal traffic, to hold the same load with fewer or smaller instances. The actual impact, however, depends on your load profile (I/O-bound or CPU-bound) and your cloud provider — this figure is not an automatic savings promise.
#
Conclusion

What to remember

On the bench cited here, the Rust frameworks all run in a narrow range — 18,000 to 22,000 req/s, 1.4-1.7 ms — far ahead of the Node.js frameworks on Node.js itself (5,766-9,340 req/s, 3.4-5.5 ms). But the runtime changes the situation as much as the language: Express on Bun almost catches up with Axum on Rust.

If you evaluate a backend on raw performance alone, require the methodology before the number: hardware, version, payload size, level of competition. Aurabase has not yet released its own figures; when it does, the methodology will come first.

READY TO DEPLOY?

Your backend in five minutes.

No credit card required · 500 MB free · 50,000 MAU