# Send many requests over one HTTP/2 connection

**For:** Rust developers sending lots of requests to the same server at once.

You check that fibre_http picked HTTP/2 for a server that offers it, then send 20 requests at the same time and see that they all share one connection.

Before you start: you need Rust with Cargo. fibre_http comes from crates.io as `fibre_http = "0"`.

## Set up the project

Start a new binary crate.

```sh
cargo new many_requests
cd many_requests
```

Put this in the `[dependencies]` section of `Cargo.toml`:

```toml title="Cargo.toml"
[dependencies]
fibre_http = "0"
tokio = { version = "1", features = ["full"] }
```

## The program

Replace `src/main.rs` with this:

```rust title="src/main.rs"
use fibre_http::{AsyncClient, Pool};

#[tokio::main]
async fn main() -> Result<(), fibre_http::Error> {
    let pool = Pool::builder().build();
    let client = AsyncClient::builder().pool(&pool).build_async()?;

    let response = client.get("https://httpbin.org/get").send().await?;
    println!("version: {:?}", response.version());
    response.bytes().await?;

    let mut tasks = Vec::new();
    for i in 0..20 {
        let client = client.clone();
        tasks.push(tokio::spawn(async move {
            let url = format!("https://httpbin.org/anything/{i}");
            client.get(url).send().await?.error_for_status()?.bytes().await
        }));
    }
    for task in tasks {
        task.await.expect("task panicked")?;
    }
    println!("21 requests, connections opened: {}", pool.connections_opened());
    Ok(())
}
```

Run it:

```shell-session
$ cargo run
version: HTTP/2.0
21 requests, connections opened: 1
```

## What each part does

When a client connects over TLS it tells the server it speaks HTTP/2 and HTTP/1.1. The server picks one. httpbin.org picks HTTP/2, which `version()` shows. You do not have to configure anything for this.

An HTTP/1.1 connection carries one request at a time. An HTTP/2 connection carries many at once. So the 20 tasks all go over the connection the first request opened, which is why the pool counts one connection for 21 requests. Over HTTP/1.1 the same program would open a connection for each request that runs at the same time as another.

A cloned `AsyncClient` shares the pool, which is why each task can take its own clone. A blocking `SyncClient` on the same pool shares the HTTP/2 connection too.

For a plain `http://` server that speaks HTTP/2 without TLS, build the client with `http2_prior_knowledge()`.

## Where to go next

The usage guide covers HTTP/2 keepalive pings and per-host connection limits: [https://github.com/excsn/fibre/blob/main/http/README.USAGE.md](https://github.com/excsn/fibre/blob/main/http/README.USAGE.md)
