# HTTP/3

URL: /pounce/docs/protocols/http3/
Section: protocols
Description: QUIC/UDP HTTP serving through the optional bengal-zoomies transport

---

> For a complete page index, fetch /pounce/llms.txt.

HTTP/3 support is optional and uses the pure-Python `bengal-zoomies` QUIC stack.
It requires TLS certificate configuration because QUIC includes TLS 1.3 in the
transport handshake.

:::{note}
HTTP/3 has its own support boundary from HTTP/1.1 and HTTP/2 because it uses a
UDP listener and QUIC transport state. Reload/drain and benchmark gates are
proven, with the bounded lifecycle exception described below.
WebSocket over HTTP/3 is not currently supported.
:::

## Install

```bash
pip install "bengal-pounce[h3]"
```

If `bengal-zoomies` is missing, the HTTP/3 path fails with an install hint:
`pip install bengal-pounce[h3]`. `pounce check` also reports the missing
HTTP/3 stack when `http3_enabled` is configured without the extra installed.

## Enable

```python
from pounce import ServerConfig

config = ServerConfig(
    host="0.0.0.0",
    port=8443,
    ssl_certfile="cert.pem",
    ssl_keyfile="key.pem",
    http3_enabled=True,
)
```

Or from the CLI:

```bash
pounce serve --app myapp:app --ssl-certfile cert.pem --ssl-keyfile key.pem --http3
```

## Tuning

| Field | Default | Description |
|-------|---------|-------------|
| `http3_enabled` | `False` | Enables the UDP/QUIC listener. |
| `http3_max_connections` | `10_000` | Maximum concurrent QUIC connections. |
| `http3_idle_timeout` | `30.0` | Idle timeout in seconds. |
| `http3_qpack_max_table_capacity` | `0` | QPACK dynamic table capacity. 0 uses static-table-only compression. |
| `http3_zero_rtt_enabled` | `False` | Allows TLS 0-RTT at the transport layer; unsafe methods receive `425 Too Early`. |

## Behavior

- Oversized request bodies are rejected with `413`.
- Malformed or contradictory pseudo-headers are rejected before ASGI scope construction.
- `Alt-Svc` is advertised from HTTP/2 responses when HTTP/3 is enabled.
- Built-in health, introspection, and compression-dictionary endpoints match
  the HTTP/1.1 and HTTP/2 paths and report the serving worker's real ID.
- Valid extension-method tokens are preserved. `QUERY` and its request body
  reach ASGI unchanged; Pounce adds no application or caching semantics.
- Lifespan state is passed into H3 ASGI scopes.
- Real-socket reload/drain tests cover generation rotation, bounded shutdown,
  and orphan-thread cleanup. Streams that finish within `shutdown_timeout`
  complete normally; over-budget streams are cancelled and QUIC closes.
- The reproducible local benchmark artifact records five Python 3.14t samples,
  persistent QUIC connections, variance, raw client output, and telemetry at
  `benchmarks/artifacts/2026-07-08/http3-pounce-local.json`. It is a protocol
  proof snapshot, not a public performance target or an HTTP/2 comparison.

HTTP/3 is therefore an optional protocol path in the proof ledger. Its QUIC
lifecycle semantics remain explicit rather than being described as identical
to TCP, and WebSocket-over-H3 remains separately unsupported.

The HTTP `QUERY` method is still an
[active IETF Internet-Draft](https://datatracker.ietf.org/doc/draft-ietf-httpbis-safe-method-w-body/).
The draft defines it as safe and idempotent, so Pounce's HTTP/3 0-RTT policy
does not classify `QUERY` with the rejected unsafe methods. Applications remain
responsible for query semantics, authorization, caching, replay tolerance, and
media-type validation.
