performancerustreqwest

How to get good performance with reqwest


I'm getting much worst performance than what I expect when running some simple requests with the reqwest crate. I wrote a simple program just to demonstrate that:

use tokio::time::Instant;

const URL: &str = "http://localhost:3000/health";

#[tokio::main]
async fn main() {
    {
        let now = Instant::now();
        reqwest::get(URL).await.unwrap();
        println!("reqwest: {:.3?}", now.elapsed());
    }
    {
        let now = Instant::now();
        ureq::get(URL).call().unwrap();
        println!("ureq: {:.3?}", now.elapsed());
    }
}

When running it I get:

$ cargo run --bin perf --release
    Finished release [optimized] target(s) in 0.08s
     Running `target/release/perf`
reqwest: 33.126ms
ureq: 543.672µs

That's a 60x difference. I've done a bit more testing with concurrent and parallel queries (some of those experiments can be seen here) and it even gets worth when increasing the parallelism.

How do I get better query performance with reqwest?


Solution

  • Profiling the program execution with samply showed that reqwest is spending most of its time in openssl::ssl::connector::SslConnector::builder on the test machine running Ubuntu 23.10.

    reqwest supports many optional features that may have an impact of the performances. In that cas, using the rustls-tls feature of the default native-tls drastically reduce the reqwest's client creation time.

    In Cargo.toml, native-tls may be disabled by specifying default-features = false on the reqwest dependency:

    [dependencies]
    reqwest = { version = "0.11.23", default-features = false, features = ["rustls-tls"] }
    

    With only that change, the same test program now produces much closer performance between reqwest and ureq:

    $ cargo run --bin perf --release
        Finished release [optimized] target(s) in 0.08s
         Running `target/release/perf`
    reqwest: 539.808µs
    ureq: 208.114µs
    

    The results are now quite close and shouldn't be read as anything significant: no effort was done to be statistically relevant.