HTTP/3 is a complete overhaul of how we send web traffic, ditching TCP for a new protocol called QUIC.
Let’s see it in action. Imagine a user requesting a webpage.
HTTP/1.1 & HTTP/2 (over TCP):
- DNS Lookup: Browser asks for the IP address of
example.com. - TCP Handshake: Browser and server exchange SYN, SYN-ACK, ACK packets to establish a reliable connection. This takes at least 3 round trips.
- TLS Handshake: Browser and server exchange certificates and keys to encrypt traffic. This takes at least 2 round trips.
- HTTP Request: Browser sends the
GET / HTTP/1.1request. - Data Transfer: Server sends back HTML, CSS, JavaScript, images, etc., broken into TCP segments.
- Head-of-Line Blocking: If one TCP segment is lost, the entire connection pauses until that segment is retransmitted, even if subsequent segments have already arrived.
HTTP/3 (over QUIC):
- DNS Lookup: Browser asks for the IP address of
example.com. - QUIC Handshake: Browser and server exchange packets to establish a secure, reliable connection. This combines the connection and TLS handshakes, often completing in just 1 round trip. QUIC is TLS 1.3 by default.
- HTTP/3 Request: Browser sends the
GET / HTTP/1.1(or2.0) request. - Data Transfer: Server sends back resources. QUIC uses "streams" for multiplexing, similar to HTTP/2, but crucially, loses head-of-line blocking at the transport layer. If a packet for one stream is lost, it only affects that specific stream, not others on the same connection.
This is what curl looks like when connecting to an HTTP/3 server:
curl --http3 https://example.com
The output is the same HTML you’d get with HTTP/1.1 or HTTP/2, but the journey the data took was fundamentally different and faster.
The core problem QUIC solves is head-of-line blocking (HOL blocking) at the transport layer. TCP, by its nature, guarantees ordered delivery of bytes. If packet N is lost, TCP won’t deliver packet N+1 until N has been successfully retransmitted and received. This is great for reliability but creates a bottleneck. In HTTP/2, multiple independent request-response streams are multiplexed over a single TCP connection. If one stream experiences packet loss, it stalls all other streams on that same TCP connection, even if their data is ready. QUIC, built on UDP, implements its own reliability and ordering mechanisms per stream. This means packet loss on one QUIC stream doesn’t impact other streams.
Consider the impact of mobile networks. A single lost packet on a flaky Wi-Fi or cellular connection can cause a noticeable delay in HTTP/1.1 or HTTP/2. With HTTP/3 and QUIC, that delay is isolated to the specific resource being fetched, allowing other parts of the page to load and render much more quickly, even in adverse network conditions. QUIC also integrates TLS 1.3 into its handshake, reducing the number of round trips needed for secure connections from 3-4 (TCP + TLS) to just 1. This further speeds up connection establishment, especially for users with high latency.
QUIC’s connection migration is another significant advantage. TCP connections are identified by the 4-tuple: source IP, source port, destination IP, destination port. If any of these change (e.g., switching from Wi-Fi to cellular data), the TCP connection breaks and must be re-established. QUIC connections are identified by a unique Connection ID, independent of IP addresses and ports. This allows a connection to persist even if the client’s IP address or port changes, providing a seamless experience for mobile users.
The magic behind QUIC’s stream-level reliability and HOL blocking elimination lies in how it manages packets and acknowledgments. Unlike TCP, where the operating system’s kernel handles retransmission logic, QUIC runs in user space. Each QUIC packet contains a packet number and a list of acknowledged packet numbers. When a packet is lost (detected by a gap in packet numbers or a lack of acknowledgment within a timeout), the QUIC implementation at the sender retransmits only the lost packet, and crucially, this retransmission is handled independently for each stream. The receiver’s QUIC layer can then deliver data from other, unaffected streams to the application while it waits for the retransmission of the lost packet for the stalled stream.
The next hurdle is understanding how HTTP/3 frames are carried within QUIC packets, and how application data is structured.