Benchmarking API Performance: Go Fiber vs. Java SpringBoot vs. Express.js

Benediktus Satriya
5 min readApr 7, 2024

--

Introduction

In today’s rapidly evolving technological landscape, choosing the right framework for developing APIs is crucial for ensuring optimal performance and scalability. With numerous options available, developers often face the dilemma of selecting the most suitable framework for their projects. In this article, we embark on a journey to benchmark the performance of three popular frameworks: Go Fiber, Java SpringBoot, and Express.js.

Benchmarking Setup

To conduct a fair comparison, we set up a standardized environment using a Virtual Private Server (VPS) with the following specifications: 1 core CPU and 1GB RAM. I use Docker to containerize each framework, ensuring consistency across deployments. Additionally, we utilized Grafana and Prometheus for monitoring server metrics, while k6 served as the load testing tool.

Let’s Get Started

Setting up the Docker images

For testing purposes, I implemented the “Hello World” APIs in Go Fiber, Java SpringBoot, and Express.js. An interesting observation was the significant difference in image sizes among them. Java SpringBoot had the largest size, weighing in at 459MB, followed by Express.js at 138MB, while Go Fiber was the most lightweight at just 16.5MB.

Load Testing with k6

To simulate real-world traffic and gauge the performance of our API endpoints, we employ k6, a powerful open-source load testing tool. The k6 script provided below is tailored to our benchmarking scenario, aiming to stress-test each API implementation under varying levels of concurrent user traffic.

import http from 'k6/http';
import { check, sleep } from 'k6';

export let options = {
stages: [
{ duration: '1m', target: 200 }, // Ramp up to 200 users over 1 minute
{ duration: '3m', target: 500 }, // Stay at 500 users for 3 minutes
{ duration: '1m', target: 300 }, // Ramp down to 300 users over 1 minute
],
thresholds: {
http_req_duration: ['p(95)<500'], // 95% of requests should be below 500ms
},
};

export default function () {
let res = http.get('http://--ip address--:8080/fiber');
check(res, {
'status is 200': (r) => r.status === 200,
'transaction time is OK': (r) => r.timings.duration < 500,
});
sleep(1); // Add a short sleep to control the request rate
}
  • The options object defines the load testing scenario with specified stages:
  1. Ramp up to 200 users over 1 minute.

2. Maintain 500 users for 3 minutes.

3. Ramp down to 300 users over 1 minute.

  • Set a threshold to ensure that 95% of requests have a duration of less than 500ms, indicating acceptable performance.

Analysis of Load Testing Results

Express Js

http_req_duration : 20.31 ms

http_reqs : 91259 -> 303 req/s

Java SpringBoot

http_req_duration : 24.16 ms

http_reqs : 90893 -> 301 req/s

Go Fiber

http_req_duration : 20.59 ms

http_reqs : 91207 -> 303 req/s

In the load testing results, we observed that Go Fiber had a few requests (specifically 5) that exceeded the 500ms threshold, unlike Express.js and Java SpringBoot, which didn’t encounter any such outliers. This suggests a slight inconsistency in Go Fiber’s performance compared to the other frameworks.

Express.js

  • Average Request Duration: 20.31 ms
  • Requests per Second: 303 req/s

Resource Utilization: CPU: Max 28%, RAM: 61%

Express.js demonstrates commendable performance with an average request duration of 20.31 ms and handling a throughput of 303 requests per second. The resource utilization remains within acceptable limits, with the CPU peaking at 28% and RAM at 61%.

Java SpringBoot

  • Average Request Duration: 24.16 ms
  • Requests per Second: 301 req/s

Resource Utilization: CPU: Max 23%, RAM: 72%

Java SpringBoot exhibits slightly higher request durations compared to Express.js, with an average of 24.16 ms. It maintains a throughput of 301 requests per second while experiencing moderate resource utilization, with CPU peaking at 23% and RAM at 72%.

Go Fiber

  • Average Request Duration: 20.59 ms
  • Requests per Second: 303 req/s

Resource Utilization: CPU: Max 28%, RAM: 57%

Go Fiber showcases similar performance to Express.js, with an average request duration of 20.59 ms and handling a throughput of 303 requests per second. Resource utilization remains efficient, with the CPU peaking at 28% and RAM at 57%.

Conclusion

  • Express.js: Offers excellent performance with low request durations and efficient resource utilization.
  • Java SpringBoot: Provides stable performance, albeit with slightly higher request durations and relatively higher resource consumption.
  • Go Fiber: Stands out with comparable performance to Express.js and efficient resource utilization, making it an attractive choice for lightweight and high-performance API development.

These findings underscore the importance of considering not only performance metrics but also resource efficiency when selecting a framework for API development. Ultimately, the choice depends on specific project requirements and preferences, with each framework offering distinct advantages and trade-offs.

--

--