11.2 HTTP/3, QPACK, Discovery and Deployment
Existing connections drag downstream requests when packets are lost, so the beacon tower is considering a trial of HTTP/3. But before going live, we must clarify discovery, fallback, and observability strategies.
HTTP/3 preserves HTTP method, status, field, and caching semantics, mapping framing and multiplexing onto QUIC. It is not a new set of REST semantics, nor is it simply "taking any HTTP/2 frame and dropping it onto UDP."
1. The Layered Structure of HTTP/1.1, HTTP/2, and HTTP/3
HTTP/1.1: semantics -> HTTP/1.1 textual framing -> TCP -> IP
HTTP/2: semantics -> HTTP/2 binary frames -> TCP -> IP
HTTP/3: semantics -> HTTP/3 frames -> QUIC -> UDP -> IPHTTP/1.1 can handle multiple requests over a single persistent connection, and pipelining allows sending multiple requests upfront. However, responses must be returned in order, and ecosystem support remains limited. Therefore, the common deployment simplification that "HTTP/1.1 allows only one request per connection" is a practical shortcut, not a fundamental limitation of the wire protocol itself.
HTTP/2 enables multiplexing of HTTP streams over a single TCP connection, resolving the response ordering and application framing head-of-line (HOL) blocking issues seen in HTTP/1.x. However, when TCP byte gaps occur, all streams must wait for the kernel to fill in the missing data. HTTP/3 mitigates this cross-stream transport HOL blocking by leveraging QUIC streams.
HTTP/3 is not inherently faster. Performance outcomes depend heavily on factors such as low-loss, low-RTT paths, warm TCP/TLS connections, UDP throttling, QUIC CPU and cryptographic implementation, server scheduling, and application-level dependencies. Real-world results should be measured based on actual target network conditions and user workloads, not assumed from the protocol name alone.
2. HTTP/3 stream type
HTTP request/response uses client-initiated bidirectional QUIC streams. Typical sequence:
request stream:
HEADERS -> optional DATA -> optional trailers(HEADERS)
response HEADERS -> optional DATA -> optional trailers(HEADERS)HTTP/3 frames do not align with QUIC packet boundaries. A single H3 frame can span multiple STREAM frames or QUIC packets, and a single QUIC packet may carry data from multiple streams.
Critical unidirectional streams:
- One HTTP/3 control stream per endpoint, carrying SETTINGS, GOAWAY, MAX_PUSH_ID, and similar control messages;
- The QPACK encoder stream;
- The QPACK decoder stream.
Closing a critical stream results in a connection error. Unknown unidirectional stream types should typically be ignored or consumed to allow for future extensions. It is not appropriate to immediately terminate the connection upon encountering all unknown types, such behavior could be exploited as an attack. Instead, resource limits should be enforced to prevent the peer from opening an unbounded number of unknown streams.
3. QPACK is Designed for Out-of-Order Stream Delivery in QUIC
HPACK relies on the globally ordered byte delivery of HTTP/2 over TCP to synchronize dynamic table updates. If the same dependency is directly applied across multiple independent QUIC streams, the compressed field section of a request stream may arrive before the dynamic-table insertion.
Each QPACK endpoint maintains its own encoder/decoder state and a view of the peer’s table:
- The encoder stream sends table insertions, duplications, and capacity instructions to the peer decoder;
- The decoder stream sends section acknowledgments, stream cancellations, and insert-count increments to the peer encoder;
- On a request stream, the field section carries information such as Required Insert Count and Base, indicating decoding dependencies.
If the decoder has not yet received the required insertions, it can block header decoding on that request stream. SETTINGS_QPACK_BLOCKED_STREAMS limits the number of streams that can be blocked by the peer, and the encoder may optionally use static or literal entries to avoid exceeding this limit. Thus, QPACK establishes a controlled trade-off between compression efficiency and head-of-line (HOL) blocking, rather than eliminating blocking entirely.
The dynamic table is synchronized between encoder and decoder pairs in each direction. It is not appropriate to simplify this to “one encoder table on the server and a completely independent decoder table on the client.” The decoder must build consistent dynamic entries according to the encoder’s instructions, even though the request streams do not arrive in global order.
4. Discovery: Alt-Svc is an HTTP field, HTTPS RR is a DNS record
The Origin server can announce an HTTP/3 alternative service using the Alt-Svc header in an HTTP/1.1 or HTTP/2 response:
Alt-Svc: h3=":443"; ma=86400Alt-Svc is an HTTP response header and cannot be queried using dig to look up an "Alt-Svc DNS record." Clients may cache alternative services and use them to initiate QUIC connections. However, the certificate presented must still validate the origin identity, clients should not trust the host name declared in the Alt-Svc header as authoritative.
DNS SVCB/HTTPS resource records (RFC 9460) can also declare service bindings, ALPN (such as h3), port or address hints, and other service-related information:
dig example.com HTTPSAn address hint is merely a suggestion; clients must still resolve the address via standard DNS record lookup (including A/AAAA records) and apply their connection policies. The hint should not be treated as a replacement for authoritative address resolution. The boundary between DNSSEC and encrypted DNS remains consistent with Section 7.1.
5. Avoid Fallback That Causes UDP Black Hole and Slows Page Load
Enterprise networks, firewalls, NAT devices, and QoS/policing rules can block or throttle UDP on port 443. HTTP clients should not treat QUIC as the sole transport path unless the application contract explicitly supports QUIC only. Browsers typically decide between protocols using cached Alt-Svc/HTTPS RR records and past network behavior, but the exact timeout values and fallback algorithms are implementation-specific.
Waiting for a long time after QUIC failure before falling back to TCP introduces a protocol fallback penalty. Techniques like Happy-Eyeballs-style protocol racing, brokenness caching, and connection reuse can reduce this penalty, but they also increase the risk of duplicate handshakes and redundant data loads. It's essential to monitor not just the final successful response, but also the attempted protocols, fallback reasons, fallback timing, and the ultimately negotiated protocol.
6. Load Balancer Must Be Able to Route Stably Based on CID
The source address in a QUIC packet can change due to NAT rebinding or migration, so routing UDP datagrams solely based on the five-tuple would break connection continuity. Common deployment pattern:
- The edge or load balancer terminates QUIC traffic;
- The load balancer decodes the server-issued CID or performs rendezvous hashing to determine the backend ID, then forwards the packet to the server that maintains the connection state;
- Use of a shared or external connection state store (which introduces high cost);
- Stateless reset key management, enabling endpoints without state to signal to peers that a connection no longer exists.
CID encoding exposes routing metadata and linkability, requiring encryption, key rotation, and versioning along with full key lifecycle management. While standards like QUIC-LB provide a general design for load-balanced CIDs, actual deployment still must address backend draining, CID issuance and retirement, stateless reset mechanisms, and key rotation.
7. 0-RTT Handling at the HTTP Layer
HTTP Early Data uses Early-Data: 1 to pass early request information upstream; if the intermediary or origin cannot securely process it, it must return 425 Too Early. Upon receiving a 425 response, the client should retry after completing the handshake, not reattempt using early data in a loop.
Policies should not rely solely on method name:
GETcan trigger logging, billing, one-time link creation, or non-compliant side effects;PUTis idempotent under HTTP semantics, but repeated processing still increases audit and notification overhead;- Authentication credentials can be replayed to the same service context in early data;
- Distributed anti-replay caches face trade-offs between consistency and availability, and no solution offers absolute replay prevention without cost.
For critical state-changing requests, the safest default is to wait for 1-RTT. When early data is truly necessary, design application-level idempotency keys, replay windows, credential scopes, and semantics for duplicate responses.
8. Runtime Observability and Packet Capture
# First confirm curl build Is support available HTTP/3
curl --version
# Allowed client Select HTTP/3, Specific behavior Check current curl Document
curl -v --http3 https://example.com/
# Try only HTTP/3, to distinguish QUIC path Is available
curl -v --http3-only https://example.com/
# QUIC Usually used UDP/443, But not protocol Hardcoding can only 443
tcpdump -ni any udp port 443The system curl may not have been compiled with an HTTP/3 backend, making the option unavailable, this does not imply that the server lacks support. Tests should record both the curl and backend versions, and should not rely permanently on a specific public test endpoint.
QUIC payload and headers are largely encrypted, so passive packet capture does not reveal HTTP fields as directly as TCP does. Observability must be combined with:
- Application access logs and traces;
- QUIC transport metrics: handshake outcomes, 0-RTT acceptance or rejection, PTO/loss, RTT, cwnd/pacing, flow control blocking, migration, and path validation;
- qlog (implementation support);
- TLS key logs combined with Wireshark (with secrets securely stored only in authorized debugging environments);
- Optional spin bits or passive signals, which are subject to privacy and configuration settings and cannot be assumed to always be present.
9. Capacity and DoS Boundary
A QUIC/TLS handshake can impose CPU and state overhead on a server over UDP. Deployment must include:
- Address validation and retry policies;
- Per-IP, per-prefix, and global handshake rate limiting;
- Compliance with 3x amplification rules;
- Limits on connections, streams, buffers, and QPACK table sizes;
- Protection for stateless reset tokens and keys;
- Size of TLS certificate chains and handshake fragmentation;
- Configuration of UDP receive buffers, batching, GRO/GSO, and worker affinity;
- Capacity for TCP HTTP/2 fallback, this cannot be eliminated simply because HTTP/3 is launched.
Opening a firewall to only UDP/443 does not complete a secure deployment. Additional considerations such as NAT timeout, load-balancer CID routing, fragment/MTU handling, QoS, DDoS protection, and observability must all undergo pressure and failure testing.
10. Acceptance Issues
- Why are HTTP/3 frames, QUIC STREAM frames, and QUIC packet boundaries different?
- Why can QPACK still be blocked, and what does
SETTINGS_QPACK_BLOCKED_STREAMSresolve? - Do Alt-Svc and DNS HTTPS RR derive from different protocols?
- Why should a QUIC load balancer not select backends solely based on the five-tuple?
- What does
curl --http3-onlyfailure indicate, and what additional client/environment evidence should be recorded? - How should HTTP 425 be retried, and why can't early data be reused?