Loading content...
When Google's networking team set out to design QUIC, they faced a fundamental architectural decision: what transport substrate should they build upon? They could attempt to extend TCP, create an entirely new IP-level protocol, or build on top of an existing transport. Their choice—User Datagram Protocol (UDP)—was neither obvious nor accidental. It was a strategic masterstroke that enabled QUIC to succeed where other transport protocol innovations had failed.
UDP as a "universal pass-through":
UDP's simplicity—essentially just a thin multiplexing layer over IP with minimal error checking—makes it the most permissive transport protocol in the Internet's arsenal. NATs translate it, firewalls allow it, load balancers route it, and middleboxes generally leave it alone. This "universal pass-through" property makes UDP the ideal substrate for QUIC's ambitious reliability and encryption layers.
By the end of this page, you will understand why UDP was chosen as QUIC's foundation instead of TCP or a new protocol, how QUIC builds reliable transport semantics on top of unreliable UDP datagrams, the deployment and traversal advantages of running over UDP, and the challenges and solutions for QUIC-over-UDP in real-world network environments.
Before exploring why QUIC uses UDP, we must understand why extending TCP wasn't viable. On the surface, TCP seems perfect: it's universally deployed, well-understood, and already provides reliable, ordered delivery. Why not add encryption and multiplexing to TCP directly?
The Ossification Problem Revisited:
TCP's wire format—the structure of TCP headers as they appear on the network—has remained essentially unchanged since RFC 793 in 1981. Not because TCP is perfect, but because the Internet ecosystem has calcified around its exact format. Middleboxes (firewalls, NATs, load balancers, intrusion detection systems) don't just route TCP packets—they parse and modify them.
Consider what happens when you try to add a new TCP option:
Firewall drops unknown options: Many firewalls strip or drop packets with unrecognized TCP options, treating them as potential attacks.
NATs corrupt extended headers: Some NATs assume fixed TCP header layouts and corrupt data when headers are longer than expected.
Middle boxes rewrite segments: Performance-enhancing proxies, WAN optimizers, and other middleboxes may reassemble or split TCP segments, breaking any assumptions about segment boundaries.
Load balancers parse headers: Many load balancers make routing decisions based on TCP header fields, failing when those fields change unexpectedly.
| TCP Extension | Goal | Deployment Outcome | Middlebox Problem |
|---|---|---|---|
| TCP Fast Open | 0-RTT connection establishment | ~0.5% of connections | Cookies dropped by firewalls, broken by proxies |
| Multipath TCP | Multiple paths per connection | Limited (Apple devices) | Unknown options stripped, path correlation broken |
| TCP ECN | Explicit congestion notification | ~10% usable paths | Middleboxes zero ECN bits treating as attack |
| TCP Window Scaling | Large windows (>64KB) | Partial success | Many middleboxes enforced 16-bit limits for years |
| TCP Timestamps | RTT measurement, PAWS | Moderate success | Some proxies strip timestamps, breaking connection |
TCP Fast Open (TFO) is particularly instructive. Designed to eliminate one round-trip on repeated connections, TFO was standardized in 2014. A decade later, it remains rarely usable because middleboxes block or corrupt TFO cookies. Even Apple, a major TFO proponent, found it worked on only a minority of network paths. This demonstrates that TCP innovation is effectively blocked by the existing ecosystem.
Kernel Implementation Friction:
Beyond wire format ossification, TCP is implemented in operating system kernels. Deploying a TCP modification requires:
Total time from design to widespread deployment: 3-7 years minimum
Compare this to QUIC's user-space deployment model, where a library update can reach production in days or weeks. The innovation velocity difference is transformative.
If TCP can't be extended, why not create an entirely new protocol with its own IP protocol number? This would seem to offer complete design freedom.
The NAT Traversal Catastrophe:
Network Address Translation (NAT) devices—which mediate between private and public IP addresses—are ubiquitous. Virtually every home router, mobile carrier network, and enterprise firewall performs NAT. And NAT devices, by design, understand only established transport protocols.
When a NAT device sees a packet with IP protocol 6 (TCP) or 17 (UDP), it knows how to:
When a NAT device sees an unknown IP protocol number, it typically has two options:
Either outcome is fatal for a general-purpose transport protocol.
SCTP was designed as a modern transport protocol with multi-streaming, multi-homing, and improved congestion control—goals strikingly similar to QUIC's. Standardized in 2000, SCTP has excellent technical properties but remains a niche protocol because NATs and firewalls don't support it. QUIC's designers studied SCTP's deployment failure carefully.
With TCP extension and new protocols ruled out, UDP emerges as the logical choice—but this isn't just a process of elimination. UDP has specific properties that make it an ideal substrate for QUIC.
UDP's Essential Properties:
The User Datagram Protocol (RFC 768, 1980) is remarkably simple: it adds only source port, destination port, length, and checksum to IP datagrams. This simplicity is its strength.
UDP Header (8 bytes):
+--------+--------+--------+--------+
| Source Port | Dest Port | (16 bits each)
+--------+--------+--------+--------+
| Length | Checksum | (16 bits each)
+--------+--------+--------+--------+
| Payload Data |
+--------+--------+--------+--------+
UDP provides:
This "nothing else" is precisely what QUIC needs. QUIC implements its own reliability, ordering, flow control, and congestion control—features that, if provided by the substrate, would conflict with QUIC's design goals.
QUIC typically uses UDP port 443—the same port as HTTPS. This is strategic: port 443 is allowed through virtually all firewalls, encrypted traffic on this port is expected, and it signals that QUIC traffic should receive the same treatment as HTTPS. Some constrained networks that block UDP still allow port 443, further improving QUIC's reachability.
UDP provides no reliability guarantees—packets may be lost, duplicated, reordered, or corrupted (beyond checksum detection). QUIC must implement all reliability mechanisms itself, giving it the flexibility to do so optimally.
Packet Numbers, Not Sequence Numbers:
Unlike TCP's sequence numbers (which count bytes), QUIC uses packet numbers (which count packets). Each QUIC packet has a unique, monotonically increasing packet number. This design choice has profound implications:
Unambiguous retransmissions: In TCP, a retransmitted segment has the same sequence number as the original, making it difficult to determine whether an ACK acknowledges the original or the retransmission. QUIC retransmissions use new packet numbers, eliminating ambiguity.
Simplified RTT estimation: Since each packet number is unique, RTT samples are unambiguous. No need for Karn's algorithm to handle retransmitted segments.
Encryption-friendly: Packet numbers serve as nonces for AEAD encryption. Unique packet numbers ensure unique nonces, satisfying cryptographic requirements.
12345678910111213141516171819202122232425262728
TCP Retransmission Ambiguity:================================Time Event---- -----T0 Send segment with SEQ=1000, payload "ABC"T1 Timeout, retransmit SEQ=1000 with same payloadT2 Receive ACK for SEQ=1003 PROBLEM: Was this ACK for original or retransmission? RTT = T2 - T0 or RTT = T2 - T1 ??? Karn's algorithm: Don't use retransmitted segments for RTT Result: RTT estimates degraded during loss periods QUIC Packet Number Clarity:===========================Time Event---- -----T0 Send packet #1000 with STREAM frame (offset 0, "ABC")T1 Timeout, retransmit as packet #1001 with same STREAM frameT2 Receive ACK for packet #1001 CLEAR: ACK is for retransmission (packet #1001) RTT = T2 - T1 (unambiguous) ACK for packet #1000 might arrive later:T3 Receive ACK for packet #1000 This tells us original wasn't lost, just delayed We can update RTT and congestion estimates accordinglyQUIC's Reliability Mechanisms:
QUIC implements the complete suite of reliability features needed for a production transport protocol:
A crucial distinction: QUIC acknowledges packets, but retransmits frames. If packet #1000 contains a STREAM frame and potentially an ACK frame, and packet #1000 is lost, the STREAM frame contents are retransmitted in packet #1001 (with a new packet number), but the ACK frame may not be—it might be obsolete. This gives QUIC fine-grained control over what needs retransmission.
A common misconception about UDP is that it lacks congestion control, making UDP-based protocols dangerous network citizens that can cause congestion collapse. This concern is understandable—raw UDP applications (like some video streamers or DDoS tools) do indeed lack congestion response. However, QUIC is a responsible network citizen.
QUIC Implements Full Congestion Control:
QUIC mandates congestion control, specified in RFC 9002. The specification requires behavior at least as conservative as TCP congestion control, ensuring QUIC doesn't "cheat" by ignoring congestion signals that TCP would respect.
Key congestion control mechanisms:
Algorithm Flexibility:
Because QUIC's congestion control is implemented in user-space libraries, operators can choose and tune algorithms without OS changes:
| Algorithm | Characteristics | Use Case |
|---|---|---|
| NewReno | Conservative, loss-based | RFC 9002 baseline, high compatibility |
| Cubic | Efficient at high BDP, loss-based | Linux default, good for high-capacity links |
| BBR | Rate-based, minimal buffering | Google default, optimal for variable paths |
| COPA | Delay-based, competitive | Low-latency applications |
Google's production QUIC uses BBR by default, which aggressively minimizes queuing delay while maximizing throughput—a profile well-suited to modern internet paths with deep buffers.
BBR (Bottleneck Bandwidth and Round-trip propagation time) was developed alongside QUIC and is particularly well-suited to it. BBR uses pacing (easy in user-space), explicit bandwidth estimation (enabled by QUIC's accurate RTT), and minimal queuing philosophy (enabled by QUIC's control over sending). The QUIC-BBR combination represents state-of-the-art congestion control.
While UDP enables QUIC's deployment, it also presents challenges that QUIC must address. The internet treats UDP differently from TCP in several ways that affect QUIC operation.
Challenge 1: NAT Timeout Behavior
NAT devices maintain state to route return packets. For TCP, this state typically persists for hours (since the NAT expects long-lived connections). For UDP, NAT state often times out in 30-120 seconds of inactivity.
QUIC Solution: QUIC endpoints send PING frames or other traffic to keep connections alive through NATs. The keepalive interval should be shorter than the NAT timeout. Connection IDs also help: even if NAT state is lost and the client's external port changes, the server can recognize the connection by Connection ID and accept the path change.
| Challenge | UDP Behavior | QUIC Mitigation |
|---|---|---|
| NAT Timeouts | State expires after 30-120 seconds | PING frames for keepalive; Connection migration handles state loss |
| Rate Limiting | Some ISPs limit UDP bandwidth | HTTP/3 fallback to TCP possible; Improved with QUIC adoption |
| Amplification Attacks | UDP source spoofing enables reflection | Address validation via Retry packets; Token-based resumption |
| Path MTU Discovery | ICMP responses often blocked | DPLPMTUD: datagram-based probing without relying on ICMP |
| Receive Buffer Limits | Kernel UDP buffers may be small | Larger buffers configurable; Pacing reduces burst requirements |
| Middlebox UDP Blocking | Some networks block UDP entirely | Fallback to TCP/TLS (HTTP/2); Happy Eyeballs parallel attempts |
Challenge 2: UDP Amplification Attacks
UDP's connectionless nature enables source IP spoofing. An attacker can send small requests with a forged source IP, causing large responses to flood the victim. DNS, NTP, and memcached have been exploited for such attacks.
QUIC Solution: QUIC mandates that servers never send more data to an unvalidated address than they have received. The Initial packet must be at least 1200 bytes (padded if necessary), and the server's response is limited to 3× this size until the client proves it can receive traffic at its claimed address.
For additional protection, servers can require Retry packets: instead of processing an Initial packet immediately, the server responds with a Retry containing an opaque token. The client must include this token in a new Initial packet, proving it received the Retry at its claimed address. Only then does the server allocate connection state.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
QUIC Address Validation with Retry Packet:============================================= Step 1: Client sends Initial packet Client (IP: 198.51.100.50) → Server Initial Packet { Version: 0x00000001 DCID: random (8 bytes) SCID: random (8 bytes) Token: empty (no prior token) Payload: CRYPTO frame with ClientHello Padding: to reach 1200 bytes minimum } Step 2: Server responds with Retry (does NOT allocate state) Server → Client (198.51.100.50) Retry Packet { Version: 0x00000001 DCID: client's original SCID SCID: new server-chosen CID Retry Token: encrypted(client_IP, timestamp, original_DCID) Retry Integrity Tag: authenticates the retry } Note: Server has NOT allocated connection state yet! If client IP was spoofed, the Retry reaches wrong host. Attacker cannot proceed without valid token. Step 3: Client proves address ownership Client → Server Initial Packet { Version: 0x00000001 DCID: server's new SCID from Retry SCID: client's original SCID Token: retry_token (proves client received Retry) Payload: CRYPTO frame with ClientHello (same as before) } Step 4: Server validates and proceeds Server validates token: - Decrypts token, checks timestamp freshness - Verifies client IP matches encoded address - Original DCID matches encoded DCID Now server allocates state and proceeds with handshake. This mechanism prevents amplification:- Attacker with spoofed IP cannot receive Retry- Without valid token, server won't allocate resources- Maximum amplification is 3× (Retry << 3 × Initial)QUIC limits the amplification factor to 3× before address validation. This means if a client sends 1200 bytes, the server can respond with at most 3600 bytes before client acknowledgment. This is critical for preventing QUIC from becoming an amplification vector like vulnerable DNS or NTP servers.
The Maximum Transmission Unit (MTU) is the largest packet size that can traverse a network path without fragmentation. Discovering the path MTU is crucial for efficient data transfer—too small wastes bandwidth on headers, too large causes fragmentation (in IPv4) or drops (in IPv6).
TCP's PMTUD Problem:
TCP path MTU discovery (PMTUD) relies on ICMP "Packet Too Big" messages from routers that need to fragment (but can't because Don't Fragment is set). Unfortunately, many networks filter ICMP, creating "PMTUD black holes" where large packets silently vanish.
QUIC's DPLPMTUD Solution:
QUIC uses Datagram Packetization Layer Path MTU Discovery (DPLPMTUD), specified in RFC 8899. Instead of relying on ICMP, DPLPMTUD actively probes the path with increasingly large packets and observes what gets acknowledged.
1234567891011121314151617181920212223242526272829303132
QUIC DPLPMTUD State Machine (simplified):========================================== ┌──────────────────────────────────────────────────────────────────┐ │ │ ▼ │┌─────────┐ ┌──────────────┐ ┌──────────────┐ ││ BASE │ ───────▶│ SEARCH │ ───────▶│ SEARCH_DONE │ ────────┘│ (1200) │ start │ (probing) │ success │ (optimal) │ revalidate└─────────┘ probe └──────────────┘ └──────────────┘ │ │ │ │ │ failure (suspected │ failure │ │ too large) │ (path changed) │ ▼ ▼ │ ┌──────────────┐ ┌──────────────┐ └─────────────▶│ ERROR │ ◀───────│ SEARCHING │ on black │ (reduce) │ │ LOWER │ hole detect └──────────────┘ └──────────────┘ States:- BASE: Using minimum safe MTU (1200 bytes)- SEARCH: Actively probing larger sizes- SEARCH_DONE: Found working MTU, periodic revalidation- ERROR: Probe failed, may reduce MTU- SEARCHING_LOWER: Path degraded, finding new working size Transitions:- Start probe: Send PADDING-only packet at larger size- Success: Probe acknowledged within timeout- Failure: Probe not acknowledged after retries- Revalidate: Periodic probing to catch path changes- Black hole: Large packets consistently fail, small succeedQUIC requires all implementations to support at least 1200-byte packets. This size was chosen because it's safely below the IPv6 minimum MTU (1280 bytes) while being large enough for efficient Initial packets containing TLS ClientHello. Initial packets must be padded to 1200 bytes to prevent amplification attacks.
Despite QUIC's advantages, some network paths don't support it. Enterprise networks may block UDP, ISPs may rate-limit it, or middleboxes may interfere. QUIC deployments must gracefully handle these situations.
Happy Eyeballs for QUIC (RFC 9312):
The Happy Eyeballs algorithm, originally designed for IPv4/IPv6 selection, has been extended for QUIC. When establishing a connection, the client attempts both QUIC (UDP) and TCP/TLS concurrently, with a slight head start for the preferred option.
Alt-Svc Advertisement:
For HTTP/3, servers advertise QUIC support using the Alt-Svc (Alternative Services) HTTP header or DNS HTTPS records. This allows clients connecting via HTTP/2 to learn that QUIC is available for future requests.
HTTP/1.1 200 OK
Alt-Svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
OR
Alt-Svc: h3=":443"; ma=86400; persist=1
This header tells clients:
h3=":443": HTTP/3 is available on UDP port 443ma=86400: Cache this information for 86400 seconds (1 day)persist=1: This alternative should persist across network changesMeasurements show QUIC is reachable on approximately 95%+ of internet paths. UDP blocking is less common than previously feared, particularly on port 443. The remaining 5% are typically corporate networks with aggressive firewall policies—and even these are increasingly permitting QUIC as HTTP/3 becomes standard.
We've explored why QUIC uses UDP and how this design decision shapes the protocol's capabilities. Let's consolidate the key concepts:
What's next:
With UDP as the substrate understood, we'll next explore one of QUIC's most transformative features: Connection Migration. This capability—enabled by Connection IDs rather than IP:port tuples—allows QUIC connections to survive network changes that would terminate any TCP connection.
You now understand why QUIC uses UDP, how this enables rapid protocol evolution, and how QUIC builds reliable transport semantics on unreliable datagrams. The UDP foundation is the key enabler for QUIC's other features—connection migration, 0-RTT, and resistance to ossification. Next, we'll explore how QUIC connections survive network changes through connection migration.