HTTP/3 and QUIC - What's About to Replace TCP
QUIC has been quietly moving from research project to production protocol for six years. Started at Google in 2012, deployed at scale by Google by 2015, taken to the IETF for standardization in 2016, and now — in late 2020 — sitting at draft 32, with the RFC expected within months. HTTP/3 — HTTP semantics over QUIC instead of TCP — is shipping in Chrome 87 and Firefox 88 development builds, and Cloudflare, Google, and Facebook are already serving substantial fractions of their traffic over it.
This is the third major revision to the web's transport stack in twenty-five years. HTTP/1.1 was 1997. HTTP/2 was 2015 and shipped over TCP+TLS. HTTP/3 abandons TCP entirely and runs over QUIC, which is built on UDP. The change is more than cosmetic — it rewrites the layering that has been stable since the early 1980s — and the reasons are worth understanding even if you do not plan to deploy HTTP/3 immediately.
What QUIC actually is
QUIC is a transport protocol that runs over UDP and provides what TCP+TLS provides, plus several things they cannot. The acronym originally stood for "Quick UDP Internet Connections" but the IETF working group dropped the expansion; QUIC is now just a name.
The structural decisions that define QUIC:
Connection establishment combines transport and TLS. TCP+TLS is two handshakes: a TCP three-way handshake to establish the transport, then a TLS handshake (1-RTT in TLS 1.3, 2-RTT in TLS 1.2) on top. QUIC merges these. A single QUIC handshake establishes the encrypted, authenticated connection in 1-RTT, with 0-RTT possible for resumption. The savings are most noticeable on high-latency connections (mobile, satellite) where each round trip costs real time.
TLS 1.3 is built in. QUIC does not run TLS as a separate layer; QUIC is TLS 1.3 with a different framing. The QUIC packet format is the unit of encryption and authentication, and the cipher suite is one of the modern AEAD ciphers from TLS 1.3 (AES-GCM or ChaCha20-Poly1305). There is no plaintext QUIC. There is no QUIC-without-encryption. The protocol is encrypted by definition.
Streams are first-class. QUIC supports multiple independent byte streams within a single connection. HTTP/2 also did this, but HTTP/2 ran over TCP, which means a single dropped TCP segment would block all HTTP/2 streams until retransmission — the head-of-line blocking problem. QUIC handles streams below the layer where head-of-line blocking happens; one stream's lost packet does not affect other streams' progress.
Connection migration is built in. A QUIC connection is identified by a Connection ID, not by the four-tuple of source/destination IP and port. If a client moves between networks (WiFi to cellular, one WiFi to another), the connection survives — the Connection ID is preserved across the IP change, and the cryptographic state lets the server verify that the new packets are from the same client. TCP cannot do this; a TCP connection is bound to its four-tuple and breaks when any of them change.
Head-of-line blocking is solved at the transport layer. This is the headline performance benefit. On a connection with multiple streams (a typical HTTP/3 page load with dozens of resources), one lost packet on stream A does not block streams B, C, and D. Each stream's data flow is independent. On lossy links — mobile networks, congested WiFi, anything that drops packets — this is a substantial latency improvement.
Forward error correction (planned, not yet finalized). QUIC's design accommodates FEC at the transport layer, sending redundant data so that lost packets can sometimes be reconstructed without retransmission. The current drafts do not include FEC; it is reserved for a later extension. Useful to know that the protocol is designed to support it.
What HTTP/3 changes
HTTP/3 keeps HTTP's semantics — the methods (GET, POST, etc.), the status codes (200, 404, 500, etc.), the headers, the bodies. It changes how those semantics are framed onto the wire.
The differences from HTTP/2:
-
No HPACK; QPACK instead. HPACK is HTTP/2's header compression algorithm, designed for an in-order TCP stream. QPACK is the equivalent for QUIC's out-of-order streams — slightly more complex but compatible with QUIC's stream independence.
-
No frame multiplexing on a single TCP byte stream. HTTP/2 framed multiple streams onto one TCP connection. HTTP/3 uses QUIC's native streams; the frames are smaller and the multiplexing is handled below.
-
No graceful degradation to HTTP/1.1 within a connection. A connection is HTTP/3 or it is not. You cannot upgrade or downgrade mid-flight.
For a typical web page load, HTTP/3 over QUIC produces: -
Fewer round trips for connection setup.
-
No head-of-line blocking when packets are lost.
-
Faster recovery from network changes.
-
Mandatory encryption — no unencrypted HTTP/3 exists.
The performance difference compared to HTTP/2 over TCP+TLS depends heavily on network conditions. On fast, low-loss connections (a wired desktop on a corporate network), the difference is small — maybe 5–10% on first page load. On lossy connections (mobile, congested wifi), the difference can be 30–50% or more. The benefit scales with network adversity.
Where deployment stands in late 2020
The major implementations:
-
Google: QUIC has been deployed at YouTube, Google Search, and other Google properties for years; HTTP/3 (the IETF version, distinct from Google's earlier "gQUIC") is rolling out through 2020.
-
Cloudflare: HTTP/3 is generally available for Cloudflare-fronted sites; you can enable it from the dashboard.
-
Facebook: Deploying HTTP/3 to a fraction of traffic, with public reports of meaningful performance improvements on mobile.
-
Fastly: HTTP/3 in beta; their
quiclylibrary is open-source and used by other implementers.
Browsers: -
Chrome: HTTP/3 enabled by default in Chrome 88 (released January 2021 — currently in beta channel).
-
Firefox: HTTP/3 in Firefox 88 development builds, expected to ship in spring 2021.
-
Safari: Apple has implemented QUIC support in iOS 14 and macOS 11, behind a feature flag for now.
-
Edge: Same as Chrome (Chromium-based).
Servers and libraries (as of October 2020): -
nginx: An experimental HTTP/3 patch from Cloudflare exists. Not in mainline nginx. nginx mainline plans to ship HTTP/3 through 2021.
-
Apache httpd: No HTTP/3 support yet.
-
Caddy v2: Experimental HTTP/3 support via the
experimental_http3global option, using the quic-go library. -
HAProxy: Experimental support via a separate branch.
-
Envoy: HTTP/3 support landing through 2020.
-
curl 7.66+: Experimental client support, requires building against quiche or ngtcp2.
-
Go: The quic-go library is the reference Go implementation.
-
Rust: Quinn and quiche are both production-quality.
For most operators, HTTP/3 is deployable in late 2020 if you are willing to use Caddy v2 or sit behind Cloudflare. It is not deployable on a standard nginx-on-Debian stack without significant manual effort. Expect this to change through 2021.
What this means for operators
Three implications worth thinking about now, even if you are not deploying HTTP/3 today.
Firewalling assumptions change. QUIC runs over UDP, on port 443 by convention. Networks that block UDP except for specific protocols (DNS, NTP, etc.) — which is most enterprise networks and a meaningful fraction of consumer ISPs — will simply fail to connect over HTTP/3. The browsers handle this gracefully, falling back to HTTP/2 over TCP, but the fallback adds latency. If you operate a network, expect to need to allow UDP/443 outbound, and possibly inbound to your servers.
Inspection is harder. HTTP/2 over TLS+TCP can be inspected by middleboxes that decrypt traffic — corporate TLS-inspection setups, intrusion detection systems, etc. — by terminating TLS at the inspector. QUIC's encryption extends down to the transport layer; the per-packet authentication makes it impossible to inspect traffic without the cryptographic state. For environments that do legitimate traffic inspection (regulated finance, healthcare), this is an operational change. The deployments will need to inspect at the application layer, before traffic enters the QUIC pipeline, or at the destination, after it exits.
The protocol stack you debug is different. Wireshark dissectors for QUIC are still maturing. Connection diagnostics (tcpdump is less useful when the transport is encrypted) require new tools — qlog for connection traces, qvis for visualization. If you have built debugging muscle around tcpdump and curl with verbose flags, expect to learn new tooling for QUIC.
The arguments against
QUIC is not universally beloved, and the criticisms are worth knowing.
Encrypted transport metadata. Some network operators argue that the encryption of transport-layer metadata removes legitimate visibility — congestion management, traffic engineering, troubleshooting — that ISPs and network engineers have relied on. The QUIC working group's response is that the metadata in question was always advisory, that middlebox abuse of TCP metadata was widespread, and that protocol ossification (the "you can't change anything because middleboxes assume TCP looks a particular way" problem) is a real cost. Both sides have a point; QUIC's designers chose the side of opacity.
UDP performance in the kernel. Linux's UDP stack has historically been slower than its TCP stack at high throughput. QUIC implementations need to compensate — by using sendmmsg, by using io_uring on newer kernels, by running parts of the stack in userspace. Performance has been improving rapidly, but TCP still has a kernel-fast-path advantage that UDP-based protocols are still catching up to.
Implementation complexity. A QUIC stack is substantially more complex than a TCP stack. The protocol specifies congestion control, loss recovery, flow control, encryption, multiple streams, connection migration, packet number protection, and a dozen other concerns at a single layer. The first few generations of QUIC implementations have had bugs at every layer, and the long tail of edge cases will take years to shake out.
The kernel inclusion question. A standard Linux kernel as of late 2020 has no in-kernel QUIC. The protocol is implemented entirely in userspace by every major implementation. There is ongoing discussion about an in-kernel QUIC, but no consensus on whether it is desirable; some argue userspace is the right place for a protocol that is still evolving rapidly.
What to do this quarter
For most operators, the practical answer in late 2020 is: do nothing yet. HTTP/3 is real, deployable for the leading edge, and will be the standard for new deployments by 2022. But the tooling for the typical Debian-Ubuntu-RHEL nginx stack is not ready, and forcing HTTP/3 into a production environment that does not support it well will cost more than it saves.
If you want to experiment now:
- Stand up a Caddy v2 instance with
experimental_http3enabled, behind a domain you control. - Test with Chrome's beta channel or a curl built against quiche.
- Note the operational differences — UDP/443 firewalling, log differences, debugging tooling.
For early-2021 production deployment, watch:
- nginx mainline HTTP/3 support (expected through 2021).
- The QUIC RFC publication (expected Q1 2021).
- The HTTP/3 RFC publication (expected mid-2021, dependent on QUIC).
The summary
QUIC and HTTP/3 are the third major revision to the web's transport. They solve real problems — head-of-line blocking, mobile network handoffs, slow connection establishment — by rebuilding the transport stack at a lower level than TCP. The encryption is mandatory, the metadata is opaque, and the implementation complexity is real.
In late 2020, the protocol is in late draft, the leading-edge deployments are in production, and the mainline server tooling is six to twelve months behind. By the end of 2021, HTTP/3 will be the standard answer for new deployments, the tooling will have caught up, and the question will be when to migrate, not whether.
Worth understanding now, deployable selectively today, mainstream by next year. Adjust your tooling accordingly.