Skip to content

Hyper unexpectedly way slower when using HTTP/2 #3071

Open
@Eijebong

Description

@Eijebong

Version
hyper 0.14.23
h2 0.3.15
tokio 1.22.0

Platform
Linux polonium 6.0.9-arch1-1 #1 SMP PREEMPT_DYNAMIC Wed, 16 Nov 2022 17:01:17 +0000 x86_64 GNU/Linux

Description

Given the following code:

use hyper::{Client, Server, Body, Response, Request};
use hyper::service::{make_service_fn, service_fn};
use std::env::args;

#[tokio::main]
async fn main() {
    let mut args = args();
    args.next();
    let http2_only = args.next() == Some("http2".into());

    tokio::spawn(async {
        let make_svc = make_service_fn(move |_| {
            async move {
                Ok::<_, hyper::Error>(service_fn(move |_req| {
                        async move {
                            Ok::<_, hyper::Error>(Response::new(Body::from(vec![])))
                        }
                }))
            }
        });
        let addr = ([127, 0, 0, 1], 3000).into();
        Server::bind(&addr).serve(make_svc).await
    });

    tokio::spawn(async move {
        let client = Client::builder()
            .http2_only(http2_only)
            .build_http();

        for _ in 0..100_000 {
            let request = Request::builder().method("POST").uri("http://127.0.0.1:3000/foo").body(Body::from(vec![1, 2, 3])).unwrap();
            let _res = client.request(request).await.unwrap();
        }
    }).await.unwrap();
}

I'm getting the following:

[eijebong@polonium] ~/code/hyper-slow (main) >>> time ./target/release/hyper-slow
./target/release/hyper-slow  0.93s user 2.55s system 99% cpu 3.477 total

[eijebong@polonium] ~/code/hyper-slow (main) >>> time ./target/release/hyper-slow http2
./target/release/hyper-slow http2  6.34s user 5.61s system 18% cpu 1:04.53 total

As you can see, if the client is set to do HTTP/2 only, the whole thing is around 20 times slower.

Now, if I remove the tokio::spawn around the client async block, I get ./target/release/hyper-slow http2 3.90s user 4.77s system 111% cpu 7.804 total which is still twice as slow as the HTTP/1 implementation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-http2Area: HTTP/2 specific.C-performanceCategory: performance. This is making existing behavior go faster.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions