I was testing the performance of reqwest in Rust but somehow the response.text().await
is taking a good 1-3 seconds to complete. I have tested the exact same page with postman and firefox and it only takes 100-300ms. I have tried multiple times and every single time Postman & Firefox are faster.
I have tried using Hyper as well with .aggregate()
and have tried using reqwest's .bytes()
and .chunk()
and they are all just as slow. The interesting thing is that .send().await
takes the normal 100-300ms as it's supposed to. Calling .content_length()
is also perfectly efficient. I also tried using Javascript's fetch()
and calling await response.json()
, but this is most certainly faster.
Also this has nothing to do with the release build as manually running the release exe is just as slow. Rust and reqwest are also fully up to date.
Here is the code:
use std::time::Instant;
#[tokio::main]
async fn main() {
let client = reqwest::Client::new();
let response = client
.get("https://registry.npmjs.org/react")
.send()
.await
.unwrap();
let now = Instant::now();
let data = response.text().await;
let elapsed = now.elapsed();
println!("{}ms", elapsed.as_millis());
}
Using reqwest::blocking
also does not make a difference:
use std::time::Instant;
fn main() {
let now = Instant::now();
let data = reqwest::blocking::get("https://registry.npmjs.org/react")
.unwrap()
.text()
.unwrap();
let elapsed = now.elapsed();
println!("{}ms", elapsed.as_millis());
}
The time the request takes does decrease if I request an endpoint with less data. For example https://registry.npmjs.org/react/is-even takes 300ms with reqwest, but still 70ms with Postman.
Any ideas what's causing this?
There are actually a lot of factors that lead to this unexpected result. Here are our findings.
application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*
header (as per the NPM Registry Docs) to significantly reduce the size of the payload and make the request faster. You can also do Content-Encoding: gzip
however this is quite a bit slower.GET·/{package}/{version}
instead of GET·/{package}
in addition to the header is a far better solution if possible in your application.Note that these findings are not 100% certain but are speculation. I will update this answer if I find more information. Happy coding!