Every web server claims to be fast, so I wonder how they define that. As someone who has written their own supposedly fast web server I only want configuration simplicity. Most web servers are unnecessarily far too complicated. In a web server here is what I am looking for: * Fast. That is just a matter of streams and pipes. More on this later. That said the language the web server is written in largely irrelevant to…
In Rust all web frameworks are fast because they all use the same stack tokio + hyper.
Ferron – A fast, memory-safe web server written in Rust
81–90 of 102 posts
Re: Ferron – A fast, memory-safe web server written in Rust
#82Re: Ferron – A fast, memory-safe web server written in Rust
#83Every web server claims to be fast, so I wonder how they define that. As someone who has written their own supposedly fast web server I only want configuration simplicity. Most web servers are unnecessarily far too complicated. In a web server here is what I am looking for: * Fast. That is just a matter of streams and pipes. More on this later. That said the language the web server is written in largely irrelevant to…
In Rust all web frameworks are fast because they all use the same stack tokio + hyper.
Here’s the rocket.rs source I used:
#[rocket::main]
async fn main() -> Result {
rocket::build()
.mount("/", rocket::fs::FileServer::from("/tmp/test"))
.ignite()
.await?
.launch()
.await?;
Ok(())
}
And do `mkdir /tmp/test && dd if=/dev/urandom of=/tmp/test/bigfile bs=1G count1` to create a 1G file, and run `time curl -o /dev/null localhost:8000/bigfile`.My nginx config:
worker_processes auto;
master_process off;
pid /dev/null;
events {}
http {
sendfile on;
access_log /dev/stdout;
error_log /dev/stderr;
server {
listen 8089;
server_name localhost;
root /tmp/test;
location / {
try_files $uri $uri/ =404;
}
}
}
launched with `nginx -c "$(pwd)"/nginx.conf -g "daemon off;"`The results for a 1GB file for me on an nvme ssd, averaged over 100 runs:
nginx: 150ms
rocket: 4 seconds
Or roughly 25x slower. Release mode makes no difference.You can definitely write slow code in rust if you’re naive about reading/writing between channels a few kilobytes at a time, which is what rocket does, vs using sendfile(2), like nginx does.
Edit: These numbers were from a few months ago... I tried it again by just pasting the above into a new project with `cargo init` and adding rocket and tokio to my deps, and it's now 2.3s in debug and 1.2s in release mode. It may have improved since a few months ago, but it's still 10x slower.
Re: Ferron – A fast, memory-safe web server written in Rust
#84Earlier quoted context omitted.
In Rust all web frameworks are fast because they all use the same stack tokio + hyper.
Fun experiment, try and benchmark a simple file download on a simple web server using rocket.rs (which also uses tokio and hyper, and has a built in fileserver type, so just a few lines of code) and compare it to a vanilla nginx config. Here’s the rocket.rs source I used: #[rocket::main] async fn main() -> Result { rocket::build() .mount("/", rocket::fs::FileServer::from("/tmp/test")) .ignite() .await? .launch() .awa…
Re: Ferron – A fast, memory-safe web server written in Rust
#85Re: Ferron – A fast, memory-safe web server written in Rust
#86Re: Ferron – A fast, memory-safe web server written in Rust
#87Earlier quoted context omitted.
In Rust all web frameworks are fast because they all use the same stack tokio + hyper.
Fun experiment, try and benchmark a simple file download on a simple web server using rocket.rs (which also uses tokio and hyper, and has a built in fileserver type, so just a few lines of code) and compare it to a vanilla nginx config. Here’s the rocket.rs source I used: #[rocket::main] async fn main() -> Result { rocket::build() .mount("/", rocket::fs::FileServer::from("/tmp/test")) .ignite() .await? .launch() .awa…
Re: Ferron – A fast, memory-safe web server written in Rust
#88Re: Ferron – A fast, memory-safe web server written in Rust
#89Re: Ferron – A fast, memory-safe web server written in Rust
#90Earlier quoted context omitted.
Fun experiment, try and benchmark a simple file download on a simple web server using rocket.rs (which also uses tokio and hyper, and has a built in fileserver type, so just a few lines of code) and compare it to a vanilla nginx config. Here’s the rocket.rs source I used: #[rocket::main] async fn main() -> Result { rocket::build() .mount("/", rocket::fs::FileServer::from("/tmp/test")) .ignite() .await? .launch() .awa…
This doesn't count because hyper doesn't support sendfile. Maybe hyper would outperform nginx in other scenarios.
Because nginx knows to tune the buffer sizes properly, which goes a long way.
Using strace reveals what’s happening, rocket is reading and writing to file descriptors 4 kilobytes at a time, using 2 syscalls every chunk. nginx uses far, far fewer of them. (And with sendfile enabled, only one for the whole download.)
Also, there’s no reason rocket can’t use sendfile too. It’s basically the theoretically fastest way to perform this operation, and IMO rocket ought to use it by default if it’s available on the OS.