The benefits of clustering Fastify app: URL shortener service use case (2024)

The benefits of clustering Fastify app: URL shortener service use case (1)

Node.js, as its default behavior, operates on a single thread and does not make full use of available CPU cores, even when multiple cores are at its disposal. However, this single-threaded approach doesn’t preclude you from harnessing the power of multiple cores within your environment.

In contrast, Node.js includes a built-in cluster module. This module facilitates the creation of child processes (referred to as workers) that can operate concurrently while sharing the same server port. Each child process functions independently with its own event loop, memory allocation, and V8 engine instance.

These child processes employ interprocess communication to establish seamless communication with the primary parent Node.js process. This capability ensures enhanced performance and resource utilization in Node.js applications running on multi-core machines.

In this article, we will analyze the performance of a URL shortener application under two different configurations: first, when it operates over Fastify in its standard mode, and second, when it runs in cluster mode with a size of 4.

Environment

All tests are executed on MacBook Pro M1 with 16G of RAM. The Node.js version is v21.0.0 (latest at the time of writing). Load testing was performed using a tailored version of the Bombardier test tool. This customized tool allowed for the sending of random URLs in each request.

Database

In the context of our URL shortener series, we have opted for the widely used PostgreSQL database. To facilitate this, we have established a straightforward table structure designed to store the short ID and corresponding original URL. The table is defined as follows:

urlshortener=> \d shortenedurls;
Table "public.shortenedurls"
Column | Type | Collation | Nullable | Default
--------------+-----------------------------+-----------+----------+---------
id | character(10) | | not null |
srcurl | character(250) | | not null |
created | timestamp without time zone | | |
lastaccessed | timestamp without time zone | | |
Indexes:
"firstkey" PRIMARY KEY, btree (id)

Before each test, the table is truncated.

Code

The URL shortener service is designed using the Model-View-Controller (MVC) architectural pattern. The controller, service, and database part is common between regular and clustered application. The differentiator is the main file where fastify application is created.

First, let’s look at the main file for both cases:

fastifyMain.mjs

import Fastify from "fastify";
import { handleRequest } from "./fastifyController.mjs";

const app = Fastify({
logger: false,
});

app.post("/shorten", handleRequest);

app.listen({ port: 3000 });

fastifyClusterMain.mjs

import cluster from "node:cluster";
import Fastify from "fastify";
import { handleRequest } from "./fastifyController.mjs";

const numClusterWorkers = parseInt(process.argv[2] || 1);

if (cluster.isPrimary) {
for (let i = 0; i < numClusterWorkers; i++) {
cluster.fork();
}

cluster.on(
"exit",
(worker, code, signal) => console.log(`worker ${worker.process.pid} died`),
);
} else {
const app = Fastify({
logger: false,
});

app.post("/shorten", handleRequest);

app.listen({ port: 3000 });
}

Next, let’s look at the common parts:

fastifyController.mjs

import { shorten } from "./service.mjs";

export async function handleRequest(req, rep) {
if (!(req.body && req.body.srcUrl)) {
return rep.code(400).send({ errMsg: "Parameter 'srcUrl' is missing" });
}

const srcUrl = req.body.srcUrl;
if (srcUrl.length > 250) {
return rep.code(400).send({
errMsg: "Parameter 'srcUrl' must not be more than 250 characters",
});
}
if (!(srcUrl.startsWith("http://") || srcUrl.startsWith("https://"))) {
return rep.code(400).send({
errMsg: "Parameter 'srcUrl' must start with http:// or https://",
});
}

const shortenedUrl = await shorten(srcUrl);
if (!shortenedUrl) {
return rep.code(500).send({ errMsg: "Failed to shorten" });
}
rep.send({ srcUrl, shortenedUrl });
}

service.mjs

import { nanoid } from "nanoid";
import { save } from "./db.mjs";
const baseUrl = "http://test.short/";

export async function shorten(srcUrl) {
if (!srcUrl) {
return;
}

const urlId = nanoid(10);
const shortenedUrl = `${baseUrl}${urlId}`;

const dbStatus = await save(urlId, srcUrl);
return dbStatus ? shortenedUrl : undefined;
}

db.mjs

import { DataTypes, Sequelize } from "sequelize";

const dbUser = process.env.dbUser;
const dbUserPass = process.env.dbUserPass;
const dbName = process.env.dbName;

const sequelize = new Sequelize(
`postgres://${dbUser}:${dbUserPass}@localhost:5432/${dbName}`,
{
logging: false,
pool: {
max: 10,
min: 10,
},
},
);
await sequelize.authenticate();

const ShortenedUrl = sequelize.define("shortenedurl", {
id: {
type: DataTypes.STRING,
primaryKey: true,
},
srcurl: DataTypes.STRING,
created: DataTypes.DATE,
lastaccessed: DataTypes.DATE,
}, {
timestamps: false,
});

export async function save(id, srcUrl) {
await ShortenedUrl.create({
id,
srcurl: srcUrl,
created: new Date(),
lastaccessed: new Date(),
});
return true;
}

The performance benchmarking involved conducting tests with 1 million requests, evaluated under varying concurrent connections of 10, 50, and 100. To conduct these load tests, a tailored version of the Bombardier load test tool was employed, as previously mentioned. Additionally, a warm-up phase consisting of 1,000 initial requests preceded each test run for accurate assessment.

A cluster size of 4 has been used for benchmarking.

Charts

If you prefer charts, the results in chart form are as follows:

The benefits of clustering Fastify app: URL shortener service use case (4)
The benefits of clustering Fastify app: URL shortener service use case (5)
The benefits of clustering Fastify app: URL shortener service use case (6)
The benefits of clustering Fastify app: URL shortener service use case (7)
The benefits of clustering Fastify app: URL shortener service use case (8)
The benefits of clustering Fastify app: URL shortener service use case (9)
The benefits of clustering Fastify app: URL shortener service use case (10)
The benefits of clustering Fastify app: URL shortener service use case (11)
The benefits of clustering Fastify app: URL shortener service use case (12)
The benefits of clustering Fastify app: URL shortener service use case (13)

Tables

If you prefer tables, here are the same results in tabular form:

The benefits of clustering Fastify app: URL shortener service use case (14)
The benefits of clustering Fastify app: URL shortener service use case (15)
The benefits of clustering Fastify app: URL shortener service use case (16)

It’s no revelation that clustered Fastify applications deliver superior performance. A thorough analysis indicates that Fastify application operating within a cluster of size 4 offers nearly 60% more performance over its regular counterpart. However, this enhancement comes with a significant trade-off, necessitating approximately four times the CPU and memory usage. If computational resources are not a constraint, opting for a clustered configuration is the ideal choice!

Note: Should you encounter any discrepancies in the comparison and anticipate updates or corrections to the article, kindly provide the revised and comprehensive application code along with evidence of improved results using the Bombardier test tool. Speculations will not be considered for article revisions.

For a comprehensive list of real-world benchmarking, you can visit the main article here.

The benefits of clustering Fastify app: URL shortener service use case (2024)

FAQs

The benefits of clustering Fastify app: URL shortener service use case? ›

A thorough analysis indicates that Fastify application operating within a cluster of size 4 offers nearly 60% more performance over its regular counterpart. However, this enhancement comes with a significant trade-off, necessitating approximately four times the CPU and memory usage.

What is the use case of fastify? ›

Use Cases of Plugins and Encapsulations in Fastify

A plugin is a software extension that can be added to enhance the functionality or capability of an application. For instance, there is a Fastify/MongoDB plugin that helps Node. js developers manage their database with MongoDB while using Fastify.

What is the use case of URL shortener? ›

An URL shortener ensures that you get the right messages out to your audience without taking up too much space in your social posts. Additionally, tools like Bit.ly: Make it easier to share your content: Some link shorteners let you create a branded URL containing your brand.

What are the benefits of fastify? ›

Fastify offers better performance, handling more requests per second with lower memory usage. It's great for high-performance and scalable apps, with modern features like built-in HTTP/2 support and easier TypeScript integration. Fastify is also better for future-ready projects.

Why use fastify instead of Express? ›

Fastify provides a good alternative framework for Nest because it solves design issues in a similar manner to Express. However, fastify is much faster than Express, achieving almost two times better benchmarks results.

Top Articles
First-Time Homebuyers: How Much Do You Really Need to Save?
Total Value to Paid-In (TVPI) Definition and Role in PE | Moonfare
Kem Minnick Playboy
Part time Jobs in El Paso; Texas that pay $15, $25, $30, $40, $50, $60 an hour online
What is Mercantilism?
Algebra Calculator Mathway
Missing 2023 Showtimes Near Cinemark West Springfield 15 And Xd
DEA closing 2 offices in China even as the agency struggles to stem flow of fentanyl chemicals
Southside Grill Schuylkill Haven Pa
Chris wragge hi-res stock photography and images - Alamy
Waive Upgrade Fee
Geometry Escape Challenge A Answer Key
Celsius Energy Drink Wo Kaufen
Infinite Campus Parent Portal Hall County
Student Rating Of Teaching Umn
Valentina Gonzalez Leaked Videos And Images - EroThots
Lima Crime Stoppers
Lonadine
Flights To Frankfort Kentucky
Transfer Credits Uncc
2015 Honda Fit EX-L for sale - Seattle, WA - craigslist
[Birthday Column] Celebrating Sarada's Birthday on 3/31! Looking Back on the Successor to the Uchiha Legacy Who Dreams of Becoming Hokage! | NARUTO OFFICIAL SITE (NARUTO & BORUTO)
Lancasterfire Live Incidents
Violent Night Showtimes Near Amc Fashion Valley 18
Bank Of America Financial Center Irvington Photos
Why Is 365 Market Troy Mi On My Bank Statement
Juicy Deal D-Art
Bellin Patient Portal
Cornedbeefapproved
Stubhub Elton John Dodger Stadium
134 Paige St. Owego Ny
Vlocity Clm
What Happened To Father Anthony Mary Ewtn
EST to IST Converter - Time Zone Tool
Craigslist Red Wing Mn
Acadis Portal Missouri
Mta Bus Forums
Caderno 2 Aulas Medicina - Matemática
Bernie Platt, former Cherry Hill mayor and funeral home magnate, has died at 90
Ig Weekend Dow
manhattan cars & trucks - by owner - craigslist
Dragon Ball Super Super Hero 123Movies
Gamestop Store Manager Pay
Ghareeb Nawaz Texas Menu
Citymd West 146Th Urgent Care - Nyc Photos
FedEx Authorized ShipCenter - Edouard Pack And Ship at Cape Coral, FL - 2301 Del Prado Blvd Ste 690 33990
Oklahoma City Farm & Garden Craigslist
Actress Zazie Crossword Clue
Morbid Ash And Annie Drew
Lorcin 380 10 Round Clip
Worlds Hardest Game Tyrone
Anthony Weary Obituary Erie Pa
Latest Posts
Article information

Author: Rubie Ullrich

Last Updated:

Views: 6013

Rating: 4.1 / 5 (52 voted)

Reviews: 91% of readers found this page helpful

Author information

Name: Rubie Ullrich

Birthday: 1998-02-02

Address: 743 Stoltenberg Center, Genovevaville, NJ 59925-3119

Phone: +2202978377583

Job: Administration Engineer

Hobby: Surfing, Sailing, Listening to music, Web surfing, Kitesurfing, Geocaching, Backpacking

Introduction: My name is Rubie Ullrich, I am a enthusiastic, perfect, tender, vivacious, talented, famous, delightful person who loves writing and wants to share my knowledge and understanding with you.