Fiber (Go) vs. Nickel.rs (Rust): A Performance Showdown in 'Hello World'

Cloud Native Pilgrim | Kubernetes Enthusiast | Serverless Believer | Customer Experience Architect @ Pulumi | (he/him) | CK{A,AD} |
Search for a command to run...

Cloud Native Pilgrim | Kubernetes Enthusiast | Serverless Believer | Customer Experience Architect @ Pulumi | (he/him) | CK{A,AD} |
Interesting benchmark! Just wondering if you have any context for why the max response time for Nickel.rs can go up to 30s?
I can only explain it, that my web server can't handle all the requests/s and timeout. I see some timeouts in the result of bombardier:
Bombarding http://127.0.0.1:6767 with 5000000 request(s) using 50 connection(s)
5000000 / 5000000 [==================================================================================================================================================================================================================================================================================] 100.00% 106194/s 47s
Done!
Statistics Avg Stdev Max
Reqs/sec 106292.69 44491.73 224577.53
Latency 393.78us 91.33ms 33.91s
Latency Distribution
50% 43.00us
75% 63.00us
90% 103.00us
95% 170.00us
99% 642.00us
HTTP codes:
1xx - 0, 2xx - 4999962, 3xx - 0, 4xx - 0, 5xx - 0
others - 38
Errors:
dial tcp 127.0.0.1:6767: connect: operation timed out - 38
Throughput: 21.90MB/s
Engin Diri It's interesting that the max delay is much lesser in Fiber, thanks for the info! :D
Discover the power of Rust - the modern systems programming language - through my insightful blog series. Dive deep into its features, benefits, and examples.
TL;DR: Le Code https://github.com/dirien/quick-bites/tree/main/rust-actix-web-rest-api-opentelemetry Introduction We keep reading about the importance of Observability in our applications. Charity Majors CEO of Honeycomb made a very good tweet thre...
GPU scheduling in Kubernetes has always felt like buying a mansion when you need a studio apartment. A small inference workload that needs 2GB of GPU memory gets scheduled on an entire 80GB A100, and there's nothing you can do about it. The device pl...

TL;DR: The code https://github.com/dirien/quick-bites Nothing is more controversial in the Kubernetes community than whether to use Helm or Kustomize. I always advocate the philosophy of using the right tool for the right job. It avoids the problem...

TL;DR Le code https://github.com/dirien/quick-bites Introduction This article is part three of my series on secret management on Kubernetes with the help of Pulumi. In my first article, we talked about the Sealed Secrets controller. The second arti...

With AWS Lambda

Disaster Recovery, Data Migration made easy!

In this article, I want to compare the performance of two different web frameworks for Rust and Go. Both frameworks are very similar in their design (all are inspired by Express.js) and both claim to be the fastest web framework (blazing fast). Both frameworks are easy to use, which is a big plus for me (I am not the smartest guy in the world, so easy is good).
For Rust, I have chosen the Nickel.rs framework. It is a minimal and lightweight framework for web apps in Rust. It is inspired by Express.js and provides a lot of features like flexible routing, middleware, JSON handling, and more. And it's blazingly fast!
As a contender for Go, I have chosen the Fiber framework. This framework is also inspired by Express.js and is built on top of Fasthttp. It has a lot of features like middleware, routing, WebSockets, and more. And it claims to have extreme performance and a small memory footprint.
The specs of my machine are Apple M1 Max (10 Core CPU) with 32GB of RAM.
The Tests will be written in bombardier and will be executed for 50, 100 and 500 concurrent users with executing 5M requests.
I use the following versions:
Go: go1.20.3 darwin/arm64
Rust: rustc 1.65.0 (897e37553 2022-11-02)
Nickel.rs (Rust)#[macro_use]
extern crate nickel;
use nickel::Nickel;
fn main() {
let mut server = Nickel::new();
server.utilize(router! {
get "**" => |_req, _res| {
"Hello world!"
}
});
server.listen("127.0.0.1:6767").unwrap();
}
Fiber (Go)package main
import "github.com/gofiber/fiber/v2"
func main() {
app := fiber.New()
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Hello, World ๐น!")
})
app.Listen(":3000")
}
Fiber (Go) | Nickel.rs (Rust) | |
| Time taken | 140s | 47s |
| Request per second | 35378.09 | 106293.29 |
| Mean response time | 1.41 ms | 0.39396 ms |
| Median response time | 0.845 ms | 0.049 ms |
| 90th percentile | 3.44 ms | 0.110 ms |
| Max response time | 107.07 ms | 33.91 s |
| CPU | 35% | 18% |
| Memory | 11.102 MB | 4 MB |
Fiber (Go) | Nickel.rs (Rust) | |
| Time taken | 184s | 51s |
| Request per second | 27073.55 | 97200.03 |
| Mean response time | 3.69 ms | 0.92 ms |
| Median response time | 2.90 ms | 0.04 ms |
| 90th percentile | 7.94 ms | 0.09400 ms |
| Max response time | 136.02 ms | 29.91 s |
| CPU | 35% | 18% |
| Memory | 13 MB | 4 MB |
Fiber (Go) | Nickel.rs (Rust) | |
| Time taken | 189s | 1m |
| Request per second | 26359.05 | 83084.80 |
| Mean response time | 18.97 ms | 5.00 ms |
| Median response time | 18.27 ms | 0.04 ms |
| 90th percentile | 31.78 ms | 0.085 ms |
| Max response time | 185.04 ms | 32.25 s |
| CPU | 35% | 17% |
| Memory | 29 MB | 4 MB |
Based on the data provided, Nickel.rs (Rust) is the winner. There are several reasons for this:
๐ Faster response times: Nickel.rs (Rust) has lower mean, median, and 90th percentile response times across all levels of concurrent users compared to Fiber (Go).
โก Higher request per second: Nickel.rs (Rust) can handle more requests per second than Fiber (Go) in each test.
๐ก๏ธ Lower CPU usage: Nickel.rs (Rust) uses less CPU (about half) compared to Fiber (Go) in all tests.
๐ง Lower memory usage: Nickel.rs (Rust) uses significantly less memory (about 3 to 7 times less) compared to Fiber ( Go) in all tests.
In conclusion, ๐ Rust (specifically Nickel.rs) outperforms Go (Fiber) in terms of response times, request handling, CPU usage, and memory consumption, making it the winner in this comparison.