Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reqwest with rustls backend is slow #1454

Closed
AzazKamaz opened this issue Jan 31, 2022 · 3 comments
Closed

Reqwest with rustls backend is slow #1454

AzazKamaz opened this issue Jan 31, 2022 · 3 comments

Comments

@AzazKamaz
Copy link

I have found that reqwest with rustls-tls is very slow while native-tls or ureq with rustls is ok.

main.rs:

use std::{io::Read, time::Instant};

#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    let url = "https://storage.yandexcloud.net/test-6a76614e-2409-410b-b81f-80f3858b0555/test.bin";


    let start = Instant::now();

    let res = ureq::get(url).call()?;
    let mut buf = Vec::new();
    res.into_reader().read_to_end(&mut buf)?;

    let end = Instant::now();
    println!("Got {} bytes in {:?} using ureq/rustls", buf.len(), end - start);


    let start = Instant::now();

    let res = reqwest::get(url).await?;
    let buf = res.bytes().await?;

    let end = Instant::now();
    println!("Got {} bytes in {:?} using reqwest/default", buf.len(), end - start);


    let start = Instant::now();

    let client = reqwest::ClientBuilder::new().use_rustls_tls().build()?;
    let res = client.get(url).send().await?;
    let buf = res.bytes().await?;

    let end = Instant::now();
    println!("Got {} bytes in {:?} using reqwest/rustls", buf.len(), end - start);


    Ok(())
}

Cargo.toml:

[package]
name = "test"
version = "0.1.0"
edition = "2021"

[dependencies]
tokio = { version = "1", features = ["full"] }
reqwest = { version = "0.11", features = ["rustls-tls"] }
ureq = "2.4.0"

Running using cargo run --release.
The url provided is random test file stored on S3-compatible Yandex.Cloud storage. I will delete it after a while.

Output on MacBook Pro M1 connected to Wireguard VPN in Yandex.Cloud:

Got 134217728 bytes in 4.381343875s using ureq/rustls
Got 134217728 bytes in 4.026342041s using reqwest/default
Got 134217728 bytes in 7.770271291s using reqwest/rustls

Output on AMD + Linux desktop:

Got 134217728 bytes in 7.048582088s using ureq/rustls
Got 134217728 bytes in 7.518476633s using reqwest/default
Got 134217728 bytes in 13.268687429s using reqwest/rustls

Also curl using time curl $URL > /dev/null downloads file with time comparable to ureq.

So tests shown that reqwest on rustls is very slow somewhy

@seanmonstar
Copy link
Owner

It wouldn't surprise me if we could improve the building time with rustls.

However, it's highly recommended that you build a Client once, instead of creating a new one for every request. That will improve your performance.

@AzazKamaz
Copy link
Author

The reason of it is that hyper with http2 is slower when downloading large files (Idk about small files or many files)

The reason why can be shown using this code is that with default configuration reqwest uses http2 only with rustls.
If we enable feature native-tls-alpn it will also prioritise http2 with native-tls

And if we do .http1_only() on ClientBuilder it will be as fast as curl

@AzazKamaz
Copy link
Author

There are a lot of open issues about it there, for example hyperium/hyper#3071

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants