§13.1
Chapter 13 · Implementation Guidance and Interoperability Testing

§13.1Server and Client Configuration Patterns for Common Deployments

RFC 9000RFC 9114

Learning objective. Learn what every QUIC/HTTP-3 deployment must configure (ALPN, certificate, transport parameters, and SETTINGS), how clients discover an HTTP/3 endpoint, and the deployment-defining challenge of load-balancing a connection identified by a connection ID rather than a four-tuple.

The four things every deployment sets #

A working HTTP/3 endpoint needs four pieces of configuration, three of which this book has already covered in depth:

  • ALPN. The TLS handshake must negotiate the token h3: "the token 'h3' is used in the Application-Layer Protocol Negotiation extension" ([RFC 9114 §3.1]). Without it there is no HTTP/3 (§2.1); ALPN is mandatory, and a failure to agree is a no_application_protocol alert ([RFC 9001 §8.1], §13.4).
  • A TLS certificate. QUIC always runs over TLS 1.3 (Chapter 2); the server is authenticated exactly as for HTTPS ([RFC 9001 §4.4]).
  • Transport parameters. The flow-control, stream-count, idle-timeout, and connection-ID limits of Chapter 7, sized to the deployment's traffic (§7.5).
  • HTTP/3 SETTINGS. Sent as the first frame on the control stream ([RFC 9114 §7.2.4], §5.1): the QPACK capacities (Chapter 6) and SETTINGS_MAX_FIELD_SECTION_SIZE.

Discovery: how a client finds HTTP/3 #

A client cannot assume a server speaks HTTP/3. QUIC is over UDP, and the server "MAY serve HTTP/3 on any UDP port" ([RFC 9114 §3.1]). The standard discovery path is HTTP Alternative Services: a server reached over HTTP/1.1 or HTTP/2 advertises its HTTP/3 endpoint "via the Alt-Svc HTTP response header field... using the 'h3' ALPN token" ([RFC 9114 §3.1.1]):

Alt-Svc: h3=":443"

The client caches that hint and, on a later request, tries QUIC first. (An HTTPS DNS record can carry the same hint so the client learns of HTTP/3 support before its first connection, a common CDN optimization, though defined outside these RFCs.)

Backend serverLoad balancerClientdiscovery — the client learns the origin also speaks HTTP/3cache it → nexttime, try QUIC first,fall back to TCP ifUDP is blockedroute byCONNECTION ID,not the 4-tuple →pick a backendHTTP/3 requests now flowthe client migrates— new address,SAME connectionIDsame CID → samebackend — statelessrouting survivesmigrationover HTTP/2 (or a prior h3 conn), a response carrying Alt-Svc:h3=":443"QUIC Initial · ALPN "h3" · DCIDchosen by the clientforward to the chosen backendhandshake · certificate · transport params · SETTINGS (first frameon control stream)packets from the new address,DCID unchangedforward to the same backend
Fig. 13.1-1A load-balanced HTTP/3 deployment. The client discovers HTTP/3 via an Alt-Svc hint, then opens a QUIC connection whose Destination Connection ID the load balancer uses to route to a backend — not the four-tuple, because that changes on migration. Because routing keys on the connection ID, a client that migrates to a new address still reaches the same backend.RFC 9114 §3.1; RFC 9000 §5.1

The deployment challenge: load-balancing by connection ID #

The single biggest way QUIC deployment differs from TCP is load balancing. A TCP load balancer routes by the four-tuple, which is stable for a TCP connection's life. A QUIC connection's four-tuple is not stable. The client can migrate to a new address (Chapter 10), and a rebinding NAT can change it involuntarily (§10.3). Routing by four-tuple would send a migrated client's packets to the wrong backend and break the connection.

QUIC's answer is the connection ID, whose whole purpose is that "changes in addressing at lower protocol layers do not cause packets... to be delivered to the wrong endpoint" ([RFC 9000 §5.1]). A QUIC-aware load balancer routes on the Destination Connection ID, and the server encodes routing information into the connection IDs it issues (§10.2) so the balancer can extract a backend identifier from any connection ID and forward statelessly. When the client migrates, the connection ID is unchanged, so the balancer keeps sending it to the same backend — migration and load balancing coexist. (The precise encoding is an operational concern; the community "QUIC-LB" design is one approach, defined outside these RFCs.)

The consequence for configuration is a coupling the chapters flagged: the server's connection-ID length and encoding must match what the balancer expects, and active_connection_id_limit must be high enough that clients always have a spare ID to migrate with (§10.2) — get either wrong and roaming clients silently land on the wrong backend.

Server and client patterns #

Beyond the load balancer, a few patterns recur:

  • Single origin. The simplest case is one server terminating QUIC directly: certificate, h3 ALPN, transport parameters, SETTINGS, done. No connection-ID encoding needed.
  • Edge / CDN. Terminate QUIC at the edge, close to users, to capture the 1-RTT and 0-RTT wins (Chapter 8); advertise HTTP/3 via Alt-Svc and the HTTPS DNS record; keep certificate chains small so the server's first flight stays under the amplification limit (§8.3).
  • Client pooling and fallback. A client should reuse one warm connection for many requests (§8.3), cache Alt-Svc hints, and, crucially, fall back to HTTP/2 over TCP when UDP is blocked. Many networks throttle or block UDP/443, so a robust client races HTTP/3 against an HTTP/2 attempt and uses whichever connects, rather than failing when QUIC cannot get out.

Worked example: a request across a migration #

Trace Figure 13.1-1. The client first talks to the origin over HTTP/2 and receives Alt-Svc: h3=":443"; it caches this. Next time it opens a QUIC connection with ALPN h3, choosing a Destination Connection ID; the load balancer reads that connection ID, extracts the encoded backend, and forwards to it. The backend completes the handshake (certificate, transport parameters, SETTINGS as the first control-stream frame) and requests flow. When the user walks onto a cellular network, the client's address changes but its connection ID does not, so the same packets, from a new four-tuple, still carry a connection ID the balancer maps to the same backend. The connection survives the migration (Chapter 10) and stays on its backend — the two mechanisms working together.

Note

"Terminate QUIC at the edge" hides real cost that TCP deployments don't have. Each QUIC connection is a TLS session with per-connection crypto state and a congestion controller, and unlike a TCP load balancer that can splice byte streams, a QUIC balancer that only routes (rather than terminates) must forward every packet to a backend that holds the keys. That is why the connection-ID routing layer exists: it lets a cheap, stateless balancer steer encrypted packets to the right stateful backend without terminating the connection. Getting that layer right (CID encoding, length, and the active_connection_id_limit) is the core operational task of an HTTP/3 deployment, and the one with no TCP equivalent.

In practice

editorial Stand up the single-origin case first and confirm end to end: ALPN negotiates h3, SETTINGS is the first control-stream frame, and a request completes. The §5.5 lab is exactly this. Only then add a load balancer, and treat connection-ID encoding as a first-class design decision coordinated between server and balancer, not an afterthought (a mismatch shows up as connections that work until the first migration, then break). Always ship the HTTP/2-over-TCP fallback: measure the fraction of users on whom QUIC fails to connect, because on real networks it is never zero, and a client without fallback simply looks broken to them.

Takeaways #

Every HTTP/3 deployment configures four things: h3 ALPN, a TLS certificate, transport parameters, and first-frame SETTINGS. Clients discover HTTP/3 via Alt-Svc (and the HTTPS DNS record), falling back to HTTP/2 over TCP where UDP is blocked. The deployment challenge with no TCP analogue is load-balancing a connection identified by a connection ID rather than a four-tuple: a QUIC-aware balancer routes on the Destination Connection ID, which the server encodes with routing information, so migration and load balancing coexist. With deployments configured, §13.2 turns to the interoperability pitfalls that break two correctly-configured stacks talking to each other.