The JS runtimes
Published in

The JS runtimes

The (hidden) cost of using framework: Fastify vs Native HTTP servers in Node.js

The web frameworks were invented / developed to make our lives easier. In Node.js world, one of the most popular web framework is express. With 23M weekly downloads, express is still running very strong even though it is more than 10 years old. The express framework makes our life easier. It has middlewares, router, automatic request/response body processing, etc. But is there a cost to pay for all the features that we may or may not be using at all? We’ve already seen the cost of using express in one of the earlier articles:

Another fairly popular web framework is called Fastify. Fastify is a web framework highly focused on providing the best developer experience with the least overhead and a powerful plugin architecture. It is inspired by Hapi and Express and as far as we know, it is one of the fastest web frameworks in town. Fastify has 700K weekly downloads, which is significantly lesser than express, which has 23M weekly downloads.

In this article, we’ll compare a hello world HTTP server in native Node.js with Fastify. Let’s find out if we pay a performance cost for using the fastify framework. If we do pay a cost, how much it is? We’ve already seen in the earlier article that, express turns out to be costly. Let’s see if the same holds true to fastify too.

The code

First, let’s look at a very simple hello world app written using fastify (the code is taken from fastify home page):

const fastify = require("fastify")({ logger: false });

fastify.get("/", () => {
return "Hello world";

fastify.listen({ port: 3000 });

Now, let’s write a very similar app in native Node.js. We’d need to develop a minimal router that can check for request method and path. Also, there needs to be top level error handling that sends a 500 response if business logic encounters any kind of unhandled error. Here is the code of such an app in native Node.js:

const http = require("http");

http.createServer((req, resp) => {
try {
if (req.method !== "GET") {
return resp.writeHead(405).end();
if (req.url !== "/") {
return resp.writeHead(404).end();
resp.writeHead(200, {
"content-type": "text/plain",
resp.end("Hello world");
} catch (e) {

Of course, the number of lines of code is more than fastify. This is because we’re building over the bare bones provided by Node.js’s HTTP module.

The environment

The performance test is executed in the following environment:

  • MacBook M1
  • 16G RAM
  • Node.js v19

The tester is a very minimal C++ app that uses high performant and stable libcurl to make HTTP requests.

The results

Let’s run some tests and find out the hidden cost. We’ll run 1M requests for different concurrency levels. We’ll run for 1, 25, 50, 100 concurrent connections.

First, let’s see the comparison for 1 concurrent connection (a total of 1M requests):

Now that was surprising! Fastify holds very well in front of the native code. In fact, Fastify processes slightly more RPS than the native code. The CPU and memory usage is about the same.

Next, let’s look at the results for 50 concurrent connections (a total of 1M requests:

Fastify continues to hold very well. This time the native code gets 5% more RPS, and that’s perfectly fine. 5% isn’t a noticeable degradation. The CPU and memory usage also stays comparable.

Next, let’s look at the results for 100 concurrent connections (a total of 1M requests:

Lastly, let’s look at the results for 200 concurrent connections (a total of 1M requests:

Well, for high concurrencies, the Fastify framework still holds great.

Now this was a total surprise. We didn’t expect Fastify to stand in the face of native code. The Fastify framework offers about the same performance as the native code. The CPU and memory usage are slightly more than native, but not by a big margin.

There seems to be a negligible cost in using Fastify framework. Highly recommended!

Thanks for reading! More articles on similar topics can be seen in the magazine: The JS runtimes.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store