An experiment testing 22 JavaScript API setups across Node.js, Deno, and Bun found that Bun consistently supports the most users, with its native HTTP server handling up to 84,000 users and frameworks like Elysia achieving high capacity. While Node.js performs well with Fastify and uWebSockets.js, and Deno with Hono, switching to Bun offers the greatest performance gains for high-load APIs, whereas HTTP/2 reduced capacity in this specific test scenario.
In this experiment, the creator tested 22 different ways to run a JavaScript API across popular runtimes and frameworks to determine which combination supports the most users. Using a Medium clone called Conduit with 19 API endpoints and a large seeded database, the tests measured real-world performance including authentication, validation, and database writes without any caching or ORM layers. The server setup involved an eight-core virtual machine for the application and a separate database server, aiming to ensure the database was not the bottleneck. Users were simulated with realistic browsing behavior, and the goal was to sustain high load with low latency and minimal failures.
The runtimes tested were Node.js, Deno, and Bun, each running various frameworks such as Express, Fastify, Hono, H3, Elysia, and others. Node.js, the long-established runtime using the V8 engine, was compared against Deno, which supports browser-style APIs and Node compatibility, and Bun, a newer runtime built on JavaScriptCore with integrated tools and its own HTTP server. The frameworks varied in design, from minimalistic routing in Express to schema validation in Fastify and lightweight web standards-based frameworks like Hono and H3. The tests also included native HTTP servers and specialized servers like uWebSockets.js.
Results showed that Bun consistently outperformed both Node and Deno across all frameworks, often by a significant margin. For example, Express on Bun supported 62,000 users compared to 40,000 on Node, and Bun’s native HTTP server reached 84,000 users, the highest in the experiment. Framework choice mattered more on Bun, with Elysia achieving the highest capacity at 76,000 users. On Node, Fastify and uWebSockets.js led performance, with Fastify supporting 46,000 users and uWebSockets.js reaching 52,000. Deno generally lagged behind but performed best with Hono at 48,000 users.
The experiment also tested HTTP/2 but found it reduced capacity and increased memory usage compared to HTTP/1.1 in this specific workload. This was attributed to the test setup where each user had a separate connection and responses were sequential, negating HTTP/2’s multiplexing advantages. The takeaway was that while HTTP/2 is beneficial in real-world browser scenarios, it did not improve performance in this high-load API testing environment.
In conclusion, if starting a JavaScript API today, the creator recommends Bun with frameworks like Elysia or Hono for maximum capacity and efficiency. For those sticking with Node, Fastify is the best choice, with uWebSockets.js as a strong alternative. Deno is viable with Hono but generally underperforms compared to Bun and Node. The experiment highlights that switching runtimes can yield more performance gains than switching frameworks within the same runtime. Existing Express apps that meet traffic needs don’t necessarily require rewriting, but runtime upgrades could be a valuable optimization.
Useful Links
- js-runtimes-benchmark GitHub repository — Directly enables replication and inspection of the benchmark experiment described in the video.
- JavaScript API Benchmark Results Website — Provides comprehensive benchmark data supporting the video’s main claims about runtime and framework performance.