Express vs Fastify: JSON processing
In the previous article, we’ve seen the performance comparison between express and fastify for a basic hello world use case. The fastify framework won the comparison by a landslide.
In this article, we’ll do a comparison with JSON data, which is the defacto standard for data exchange over API calls.
Environment
Test environment
The test environment is:
- MacBook M1 with 16G RAM
- Node.js v19.2.0
Test scenario
A JSON body (shown below) is sent in the HTTP request. The SUT creates a v4 UUID, attaches it to a cloned request body, and then sends it back in the HTTP response.
[
{
"_id": "632fed8b3ffeb09e1ee6eb17",
"index": 0,
"guid": "4d100db7-254e-4823-81c2-3638bbc97c2b",
"isActive": false,
"balance": "$1,342.84",
"picture": "http://placehold.it/32x32",
"age": 26,
"eyeColor": "brown",
"name": "Watkins Mitchell",
"gender": "male",
"company": "XINWARE",
"email": "watkinsmitchell@xinware.com",
"phone": "+1 (819) 522-2480",
"address": "164 Louisiana Avenue, Moraida, Oregon, 2272",
"about": "Laborum magna dolore reprehenderit dolore occaecat deserunt sit nulla. Dolor quis officia nulla voluptate minim reprehenderit cillum sit quis enim tempor labore aliquip velit. Ea ut aliqua sunt velit. Culpa dolor officia laborum sit fugiat consectetur. Occaecat et quis ipsum sunt laborum deserunt minim mollit fugiat.\r\n",
"registered": "2020-08-01T06:20:59 +07:00",
"latitude": -2.984776,
"longitude": 14.016787,
.... truncated
The complete JSON can be seen here.
Code
Surprisingly, the code is almost the same in express or fastify.
Fastify
const fastify = require("fastify")({ logger: false });
const crypto = require("crypto");
fastify.post("/", (req, res) => {
return Object.assign({}, req.body, { txnId: crypto.randomUUID() });
});
fastify.listen({ port: 3000 });
Express
const express = require("express");
const crypto = require("crypto");
const app = express();
const port = 3000;
app.use(express.json());
app.post("/", (req, res) => {
res.send(Object.assign({}, req.body, { txnId: crypto.randomUUID() }));
});
app.listen(port, () => console.log("Listening on", port));
As we can see, the code is almost the same.
Tester
To keep minimal overhead from the tester side, the tester is a very simple multithreaded C++ application that uses battle tested libcurl to make HTTP requests. All the tester does is make request, receive response, and record the time taken. Nothing else.
Results
It is important to see how the framework behaves for a different level of concurrent connections. We’ll check the results for 25, 100, and 200 concurrent connections. In other words, we’ll check results for low, medium, and high concurrency.
A total of 1M (one million) requests are sent from the tester to the application. Depending on the number of concurrent connections, the total of 1M gets divided into each thread. For example — for 25 concurrent connections, each tester thread gets to execute 40K requests. And for 200 concurrent connections, each tester thread gets to execute 5K requests.
First we’ll see the results for 25, 100, and 200 concurrent connections. The results will be followed by a brief analysis.
25 concurrent connections
100 concurrent connections
200 concurrent connections
Analysis
As soon as JSON processing is added, the RPS falls down when compared to the simple hello world case.
At low concurrency (25), express was able to offer 21K RPS for hello world, while for JSON, express offers 9.5K RPS. For the same low concurrency, fastify was able to offer 81K RPS for hello world, while for JSON, fastify offers 16.5K RPS. That’s a huge drop. For JSON processing, fastify is still faster than express by a margin of 75% (less than double).
At very high concurrency (200), express was able to offer 16.7K RPS for hello world, while for JSON, express offers 8K RPS. For the same low concurrency, fastify was able to offer 46.8K RPS for hello world, while for JSON, fastify offers 15.5K RPS. For JSON processing, fastify is still faster than express by a margin of 95% (about double).
To conclude, fastify is about 80–100% faster than express for JSON processing. Fastify uses less CPU and memory when compared to express. You can get about twice the RPS with fastify.
Thanks for reading! More articles on similar topics can be seen in the magazine: The JS runtimes.