5 min read #networking #HTTP
On this page

HTTP/3

HTTP/3 runs HTTP on QUIC—no longer dependent on TCP, encapsulated via UDP, with fully independent streams (no head-of-line blocking). QPACK replaces HPACK, enabling 0-RTT connection resumption. HTTP semantics remain unchanged, but the transport layer is completely rewritten.

Overview

HTTP/3 (RFC 9114, 2022) migrates HTTP from TCP to QUIC (UDP), addressing HTTP/2's most significant remaining issue: head-of-line blocking at the TCP layer. Packet loss in one stream no longer blocks other streams. QUIC's connection migration also ensures that switching between mobile networks (WiFi ↔ 4G) does not break the HTTP connection. QPACK replaces HPACK to resolve the dynamic table head-of-line blocking in header compression. HTTP/3 uses exactly the same semantics as HTTP/2—only the transport layer has changed.

HTTP/3 = HTTP/2 semantics + QUIC transport

HTTP/3 retains all of HTTP/2's semantics (streams, multiplexing, headers, methods, status codes) but replaces the transport layer: TCP → QUIC (UDP).

Key changes:

  • Stream: No longer frame multiplexing over a TCP byte stream → QUIC streams are a protocol-first concept
  • HPACK → QPACK: Resolves HPACK's "dynamic table update loss → HOL blocking"
  • TLS 1.3: Mandatory (QUIC has built-in encryption; no plaintext HTTP/3)
  • Server Push: Deprecated (removed by Chrome and nginx)

QPACK

HPACK's problem: If a HEADERS frame containing a dynamic table update is lost → the receiver cannot decode subsequent HEADERS → HOL blocking again!

QPACK: Dynamic table updates and data frames are transmitted over different unidirectional streams in QUIC:

  Encoder Stream (unidirectional, QPACK encoder → decoder):
    Table updates: Insert (name, value) + TSS (Table State Synchronize)
  
  Decoder Stream (unidirectional, decoder → encoder):
    Feedback: Section Acknowledgment, Stream Cancellation

  Request/Response streams (bidirectional):
    HEADERS + DATA frames (referencing dynamic table indices)

  → Loss of table updates only blocks the Encoder Stream (table updates), not request/response streams!

Deployment: Alt-Svc

HTTP/2 or HTTP/1.1 response header:
  Alt-Svc: h3=":443"; ma=86400

  h3: HTTP/3 over QUIC
  ma (max-age): Remember this alternative for 86400 seconds
  :443: QUIC port (usually the same port)

  Browser: Upon receiving Alt-Svc → when connecting to the same host next time → preferentially attempt QUIC:443
          → If QUIC fails (UDP blocked, QUIC version mismatch) → fallback to TCP

References

  • RFC: 9114, 9204
  • Tools: curl --http3 -v, Chrome chrome://net-internals/#http3

Keywords: HTTP/3, QUIC, QPACK, Alt-Svc, connection migration, 0-RTT, unidirectional streams