Node.js vs Deno vs Bun: Fastify hello world server benchmarking

Mayank C
Tech Tonic

--

Introduction

This article responds to one of the most frequently requested updates: a fresh comparison of technologies like Deno and Bun, which have recently enhanced their server capabilities. Deno, starting from version 1.36, has introduced a highly efficient HTTP server called “flash,” while Bun has reached its 1.0 release milestone, boasting improved performance and reduced resource consumption. Node.js, the king of JS runtimes, doesn’t even bother to offer anything faster than what they’ve. Given these significant developments, at least on Deno and Bun, it’s evident that an updated comparison is long overdue.

In this article, we’ll take a look again at the fastify based HTTP servers in Node.js, Deno, and Bun.

Without any delay, let’s dive right into configuring our test environment.

Test setup

In this section, we will conduct benchmark tests using a MacBook Pro M1 with 16GB of RAM as our testing environment. The load testing tool employed for these tests is Bombardier. To ensure the accuracy of our assessments, we are using the most current software versions available at the time of writing:

- Node.js v20.6.0
- Deno 1.36.4
- Bun v1.0.1

Code

The focus of this article is solely on fastify HTTP servers. We’ve already seen how native servers & express servers perform for a simple hello world case.

The fastify application code remains consistent across all three technologies — Node.js, Deno, and Bun. In essence, the identical fastify application seamlessly operates within the Node.js, Deno, and Bun environments. To add an extra layer of intricacy, we are generating a nanoid and including it in the response headers.

import Fastify from "fastify";
import { nanoid } from "nanoid";
const fastify = Fastify({ logger: false });

fastify.get("/", (request, reply) => {
reply.header("x-req-id", nanoid(10));
reply.send("Hello world!");
});

fastify.listen({ port: 3000 });

Note: There is some issue with Bun in running fastify app. The app runs fine and responds to HTTP requests. However, there are errors at the application startup.

> bun run node_fastify_hello_world.mjs 
331 | family: isIPv6(address) ? "IPv6" : "IPv4",
332 | port: this.#server.port
333 | };
334 | }
335 |
336 | listen(port, host, backlog, onListen) {
^
error: Failed to start server. Is port 3000 in use?
at listen (node:http:336:16)
at /Users/mayankc/Work/source/perfComparisons/nodejs/node_modules/fastify/lib/server.js:193:4
at /Users/mayankc/Work/source/perfComparisons/nodejs/node_modules/fastify/lib/server.js:149:8
at node:dns:11:70
at processTicksAndRejections (:1:2602)
331 | family: isIPv6(address) ? "IPv6" : "IPv4",
332 | port: this.#server.port
333 | };
334 | }
335 |
336 | listen(port, host, backlog, onListen) {
^
error: Failed to start server. Is port 3000 in use?
at listen (node:http:336:16)
at /Users/mayankc/Work/source/perfComparisons/nodejs/node_modules/fastify/lib/server.js:193:4
at /Users/mayankc/Work/source/perfComparisons/nodejs/node_modules/fastify/lib/server.js:149:8
at node:dns:11:70
at processTicksAndRejections (:1:2602)
331 | family: isIPv6(address) ? "IPv6" : "IPv4",
332 | port: this.#server.port
333 | };
334 | }
335 |
336 | listen(port, host, backlog, onListen) {
^
error: Failed to start server. Is port 3000 in use?
at listen (node:http:336:16)
at /Users/mayankc/Work/source/perfComparisons/nodejs/node_modules/fastify/lib/server.js:193:4
at /Users/mayankc/Work/source/perfComparisons/nodejs/node_modules/fastify/lib/server.js:149:8
at node:dns:11:70
at processTicksAndRejections (:1:2602)
^C

Results

In order to assess the performance of technologies such as Node.js, Deno, and Bun, we conducted a series of tests. Each test involved the execution of 5 million requests under three different scenarios: 50 concurrent connections, 100 concurrent connections, and 300 concurrent connections. The test results have been visually represented in chart format for easy analysis and interpretation.

Verdict

This time around, Node.js outperforms both Deno and Bun for a simple fastify based application. Bun is the worst of the three. Bun offers less performance at very high resource (memory usage) cost.

WINNER: Node.js

A similar comparison with Express can be seen here & another one with native servers can be seen here.

--

--