QUIC and HTTP/3: changing the transport beneath HTTP

HTTP/3 maps HTTP semantics onto QUIC, a secure UDP-based transport designed for independent streams and protocol evolution.

  • HTTP history
  • HTTP/3
  • QUIC
  • QPACK
  • TLS
  • multiplexing
  • transport
  • protocol ossification

HTTP/3 began with a transport constraint

HTTP/2 gave each request-response exchange an independent application-layer stream, but all frames still traveled inside one ordered TCP byte stream. When a TCP segment was lost, the operating system could not deliver later bytes to HTTP/2 until the gap was repaired. Frames for otherwise unrelated streams waited together.

No change to HTTP/2 frame scheduling could remove that transport behavior. A solution needed a transport that exposed several reliable streams without forcing all of their bytes through one delivery order.

Changing a widely deployed transport is difficult. TCP is implemented in operating-system kernels and recognized by network address translators, firewalls, load balancers, and traffic-management devices. New TCP extensions can take years to reach users, and middleboxes may reject or rewrite behavior they do not recognize.

QUIC approached both problems together: implement a secure multiplexed transport in user space, carry its packets in UDP datagrams that existing networks already know how to route, and encrypt most transport control information so intermediaries cannot casually depend on details that need to evolve.

Google QUIC supplied deployment experience before IETF QUIC

The Chromium project’s recorded timeline starts Google QUIC work in 2012, small Chrome experiments in 2013, and wider deployment in 2014. Google brought the work to the IETF in 2015. The IETF QUIC working group was formed in 2016 to develop standards-track specifications based on pre-standardization implementation and deployment experience.

IETF QUIC was not a wire-compatible rubber stamp of Google QUIC. The design and HTTP mapping evolved through working-group drafts and interoperability testing. The transport and HTTP application mapping were also separated more cleanly: QUIC became a general secure transport, while HTTP/3 became one application protocol using it.

RFC 9000, RFC 9001, and RFC 9002 were published in May 2021 for QUIC version 1, its use of TLS, and its loss detection and congestion control. RFC 9114 followed in June 2022 to define HTTP/3.

QUIC uses UDP, but it is not unreliable HTTP

“HTTP/3 uses UDP” is true at the packet-carriage layer and misleading as a description of application behavior. Endpoints exchange UDP datagrams containing QUIC packets, but QUIC itself provides:

  • connection establishment;
  • reliable ordered delivery within each stream;
  • acknowledgment and retransmission;
  • loss detection;
  • congestion control;
  • connection-level and stream-level flow control;
  • cryptographic protection;
  • server authentication, with optional client authentication; and
  • connection migration support.

An HTTP response is therefore not exposed to an application as an unordered collection of best-effort UDP messages. QUIC recovers lost stream data and delivers each stream’s bytes in order.

The important difference from TCP is the scope of ordering. TCP presents one ordered byte stream for the whole connection. QUIC presents many ordered streams:

QUIC packet 101: Stream 0 bytes 0–999
QUIC packet 102: Stream 4 bytes 0–799
QUIC packet 103: Stream 8 bytes 0–599   [lost]
QUIC packet 104: Stream 4 bytes 800–1499

Expected result: stream 4 can continue delivering data while stream 8 waits for its missing bytes; loss does not inherently block every stream.

Loss can still affect several streams if one lost packet carried frames from each. Congestion control also applies across the connection, so packet loss can reduce the sending rate. QUIC avoids cross-stream delivery blocking; it does not make loss free.

TLS is part of QUIC’s connection machinery

QUIC version 1 integrates the TLS 1.3 handshake rather than layering an ordinary TLS record stream over the transport. TLS normally authenticates the server, can optionally authenticate the client, and derives keys, while QUIC protects packets and carries handshake data in dedicated cryptographic frames.

This integration can combine transport and cryptographic setup. A client with no previous relationship can generally establish keys and begin application communication without separate TCP and TLS handshakes. A returning client may be able to send 0-RTT application data using previously established configuration.

Zero-round-trip data has replay risk. A network attacker can replay early data under conditions described by TLS and QUIC. Applications therefore must not treat 0-RTT as safe for arbitrary state-changing operations merely because QUIC delivered it successfully. Protocol latency features do not override HTTP method semantics or application replay defenses.

Encryption also covers much more transport metadata than traditional TCP. That limits passive network diagnosis and some middlebox policy, but it reduces the chance that the network will ossify around fields endpoints need to change. Endpoints expose intentional observability through logs and measurement formats rather than relying only on readable packets.

Connection IDs let a connection survive address changes

TCP connections are conventionally identified by source and destination addresses and ports. Moving from Wi-Fi to a mobile network changes that tuple and normally breaks the connection.

QUIC uses connection IDs selected by endpoints so packets can remain associated with a connection when lower-layer addressing changes. The endpoint validates a new path before using it fully, and deployments must route connection IDs to the correct server instance.

Migration is a capability, not a guarantee of uninterrupted applications. Servers can disable active migration, load balancers need compatible routing, network policy may block the new path, and privacy rules constrain how connection IDs are reused. Still, making address continuity a transport concept is a major departure from the connection identity assumed by HTTP over TCP.

HTTP/3 maps each exchange onto a QUIC stream

HTTP/3 retains HTTP’s methods, statuses, fields, and representations. A request-response exchange normally occupies one client-initiated bidirectional QUIC stream. HTTP/3 frames such as HEADERS and DATA are carried within that stream.

Connection-wide settings and coordination use separate unidirectional control streams. HTTP/3 relies on QUIC for stream creation, stream termination, flow control, and transport reliability instead of recreating HTTP/2’s stream layer.

The architecture is similar enough to HTTP/2 that applications can preserve the same semantic interface, but different enough that HTTP/2 frames cannot simply be copied into QUIC packets. Several HTTP/2 features are subsumed by QUIC, and the absence of a single total stream order changes field compression.

QPACK adapts compression to independent delivery

HTTP/2 HPACK updates a dynamic table in the order field sections arrive on the TCP connection. QUIC does not guarantee one delivery order across streams. If HTTP/3 used HPACK unchanged, a field block on one stream could refer to a table update trapped behind loss on another stream, recreating cross-stream blocking through compression state.

QPACK separates table instructions onto dedicated unidirectional streams. Encoded field sections can refer to dynamic entries, while acknowledgments and limits let an encoder control how much blocking risk it creates.

The tradeoff is explicit:

  • referencing newer dynamic entries can improve compression;
  • a decoder may have to wait until those entries arrive; and
  • avoiding risky references reduces blocking but may send more bytes.

QPACK does not promise zero blocking. It lets implementations balance compression efficiency and latency within negotiated limits.

Clients discover HTTP/3 and retain a fallback

The https URI scheme does not encode an HTTP version. A URL remains https://example.test/ whether a client uses HTTP/1.1, HTTP/2, or HTTP/3 to the next hop.

A server can advertise an alternative HTTP/3 service through Alt-Svc, and also through HTTPS DNS records in supporting clients:

HTTP/2 200
Alt-Svc: h3=":443"; ma=86400

Expected result: the client may attempt HTTP/3 at the advertised endpoint for future requests while retaining the origin’s identity and a fallback path.

The first request may use HTTP/2, with later requests moving to HTTP/3 after the client learns support. A client can race connection attempts or fall back when UDP is blocked. HTTP/3 is therefore not a permanent site migration in which HTTP/2 clients stop working; versions coexist and are selected per connection.

An intermediary can also terminate HTTP/3 at the edge and use another HTTP version upstream. Observing h3 in a browser says nothing by itself about the CDN-to-origin connection.

UDP carriage creates real deployment costs

Using UDP avoids waiting for operating-system TCP changes, but it moves more transport responsibility into the QUIC implementation. Endpoints must implement loss recovery, congestion control, packet protection, path validation, flow control, and anti-amplification behavior correctly.

Operational tradeoffs include:

  • some networks block or rate-limit UDP;
  • encrypted transport metadata changes troubleshooting practices;
  • high packet rates can increase CPU cost without careful implementation;
  • load balancers need connection-ID-aware routing strategies;
  • servers must defend against spoofed-source amplification; and
  • implementations need pacing and congestion behavior that remains fair to other traffic.

These are not arguments that QUIC is “worse than TCP.” They explain why a transport transition requires years of production measurement and interoperability work rather than only a faster benchmark.

QUIC was designed to leave room for another QUIC

RFC 8999 defines a small set of version-independent invariants and warns observers not to assume that visible QUIC version 1 details will remain true. Version negotiation and reserved values exercise the machinery used to select future versions.

This is a direct response to protocol ossification. When middleboxes infer semantics from an implementation detail, changing that detail can break traffic even if both endpoints support the change. QUIC protects most details and documents the few invariants a network can safely recognize.

Whether future QUIC versions can avoid ossification will be proven by actual deployment, not by intent alone. The design nevertheless treats evolvability as a protocol requirement rather than an afterthought.

HTTP/3 completed a change that HTTP/2 could not make alone

HTTP/2 demonstrated that HTTP semantics could survive a completely different framing layer. HTTP/3 extended that separation to the transport:

  • HTTP semantics remain version-independent.
  • HTTP/3 frames carry those semantics on QUIC streams.
  • QUIC provides secure transport, recovery, flow control, and connection continuity.
  • UDP supplies datagram carriage through the existing Internet.

The result is not “HTTP made unreliable for speed.” It is a reliable HTTP mapping over a transport whose unit of ordered delivery matches HTTP’s multiplexed exchanges more closely than one connection-wide TCP byte stream.

That architectural alignment is HTTP/3’s historical significance. It also leads to the broader question in the final part of this series: how has HTTP kept one application model recognizable while repeatedly replacing the machinery beneath it?

Primary sources