Skip to content

Reqwest with rustls backend is slow #1454

Closed

Description

@AzazKamaz

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

Activity

  1. seanmonstar commented on Jan 31, 2022

    @seanmonstar
    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.

  2. AzazKamaz commented on Jan 9, 2023

    @AzazKamaz
    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

  3. AzazKamaz commented on Jan 9, 2023

    @AzazKamaz
    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions