Cameleeringsimoom

simoom / Use cases / HTTP/3

HTTP/3 over QUIC

HTTP/3 from Rust, without adding a stack

Mobile clients on lossy networks benefit from HTTP/3 over QUIC. In Rust that usually means quinn, h3, rustls and an async runtime, or nginx in front. simoom implements QUIC v1, HTTP/3, QPACK and TLS 1.3 itself: HTTP/3 is a cargo feature on the same server, listening on the same port number as TLS.

1.65xthe HTTP/3 requests per second of quinn + h3 on the same droplet; H2O answered 43% more than simoom (campaign 4)
54 of 58supported QUIC Interop Runner pairs against ngtcp2, quiche and quic-go
1 linemore on the builder: listen_quic on the TLS port
0external crates: QUIC, QPACK and TLS 1.3 are in the repository

TLS, HTTP/2 and HTTP/3 on one port

Build with --features full, or with tls and http3. Over TCP the client and server agree on HTTP/2 or HTTP/1.1 during the TLS handshake; the QUIC listener serves HTTP/3 on the same port number and is announced to browsers with alt-svc.

use simoom::tls::{certgen, CertifiedKey, ServerConfig};
use simoom::{Reply, Request, Server};

// a self-signed certificate for local testing; load your own PEM files in production
let cert = certgen::self_signed("localhost");
let key = CertifiedKey::from_pem(cert.cert_pem.as_bytes(), cert.key_pem.as_bytes()).expect("certificate and key");
let tls = ServerConfig::new(key);

let server = Server::builder()
    .listen_tls("0.0.0.0:8443")
    .tls(tls.clone())
    .listen_quic("0.0.0.0:8443") // HTTP/3, announced with alt-svc
    .quic_tls(tls)
    .service(|_: &mut Request<'_>, r: Reply<'_>| r.body_static(b"Hello over TLS"))
    .start()
    .expect("start");

Guides: HTTP/2 and HTTP/3 and TLS.

Measured against H2O, quinn + h3 and Caddy

Benchmark campaign 4, 2026-11-12: each server on the same DigitalOcean c-4 droplet (4 dedicated vCPUs) as simoom, in the same rounds, with load from two separate machines at a fixed rate. simoom's figure is from the same droplet as the server it is compared with, so it differs from row to row.

measuresimoomother server
HTTP/3, 64 clients, req/s with 99% within 1 ms: against H2O52,259H2O 75,055
the same, against quinn + h383,613quinn + h3 42,518
the same, against Caddy52,259Caddy 3,370
Peak memory while serving HTTP/3 (PSS): against H2O42,425 KBH2O 24,300 KB
the same, against quinn + h343,623 KBquinn + h3 57,583 KB
TLS 1.3 handshakes per second, full / resumed (TCP), against H2O9,431 / 10,303H2O 6,615 / 6,458
Start-up to first answer, full server, against quinn + h31.46 msquinn + h3 1.96 ms
Program size, stripped, full server, against quinn + h31,550 KBquinn + h3 5,766 KB

Median of rounds (three for throughput and memory, one for start-up and size). Method and raw results: benchmarks.

What the QUIC stack does, and doesn't

Supported

  • QUIC v1 (RFC 9000, 9001, 9002), HTTP/3 (RFC 9114), QPACK (RFC 9204).
  • Retry, session resumption, key update, address rebinding and IPv6.
  • WebSocket over HTTP/3 (RFC 9220), with the websocket-h3 feature.
  • A client that moves to HTTP/3 when a server offers it in Alt-Svc, and falls back to TCP.

Not supported

  • 0-RTT: refused by design (replayable early data).
  • ECN: not implemented.
  • Migration to a server's preferred address.
  • A general QUIC transport API: simoom's QUIC exists to carry HTTP/3. For raw QUIC streams use quinn or s2n-quic.

The four failed interop pairs are 0-RTT and ECN. HTTP/3 servers start every event loop at once (a socket added later to a SO_REUSEPORT group would take over some established QUIC connections), so in campaign 4 the full server, with TLS and HTTP/3, gave its first answer 1.49 ms after start, against 0.94 ms for the default build without them.

Common questions

Is there a Rust HTTP/3 server without quinn or tokio?

Yes. simoom implements QUIC v1, HTTP/3, QPACK and TLS 1.3 itself with only the Rust standard library, and has no async runtime.

Can HTTP/3 share a port with HTTPS?

Yes. listen_tls and listen_quic can use the same port number: TCP carries HTTP/2 and HTTP/1.1, UDP carries HTTP/3, and the server announces HTTP/3 with alt-svc.

How fast is simoom's HTTP/3?

H2O is faster. In benchmark campaign 4 (2026-11-12), with 64 clients and 99% of answers within 1 ms, H2O answered 75,055 HTTP/3 requests per second against simoom's 52,259 on the same droplet (43% more), and used 43% less peak memory doing it. On its droplet simoom answered 83,613 against 42,518 for quinn with h3 (1.65x), and far more than Caddy.

Does simoom support QUIC 0-RTT?

No. 0-RTT is refused by design, because early data can be replayed. ECN and migration to a preferred address are not implemented either.

Does it interoperate with other QUIC implementations?

In the QUIC Interop Runner, server role, it passes 54 of 58 supported pairs against the ngtcp2, quiche and quic-go clients. The four failures are 0-RTT and ECN.

Turn on HTTP/3

Add the features, add the QUIC listener, and test with a client that speaks HTTP/3.

cargo add simoom --features full
curl --http3-only -k https://localhost:8443/   # with a curl built with HTTP/3