Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Why QUIC Exists

QUIC wasn’t created to replace TCP for its own sake. It addresses specific, persistent problems that couldn’t be solved within TCP’s constraints.

Problem 1: TCP Head-of-Line Blocking

TCP guarantees ordered delivery of a byte stream:

Application sends:
  write(1000 bytes)
  write(500 bytes)
  write(700 bytes)

TCP segments sent:
  Segment 1: bytes 0-999
  Segment 2: bytes 1000-1499
  Segment 3: bytes 1500-2199

If Segment 2 is lost:
  Segment 3 arrives, but TCP buffers it
  Application sees nothing until Segment 2 retransmitted

With HTTP/2:
  Stream A data in Segment 1
  Stream B data in Segment 2 (lost)
  Stream C data in Segment 3

  Stream C waits for Stream B retransmit!
  Even though they're independent streams.

QUIC Solution

QUIC streams are independent:

  Stream A ─────────────────────────> Delivered immediately
  Stream B ─────X────[retransmit]──> Delivered when ready
  Stream C ─────────────────────────> Delivered immediately

Each stream has its own sequence space.
Loss on one stream doesn't block others.

Problem 2: Connection Establishment Latency

TCP + TLS requires multiple round trips:

TCP + TLS 1.2: 3 RTT before first byte
┌──────────────────────────────────────────────────────────────────┐
│  TCP SYN       ──────────────────────────────────>               │
│  TCP SYN-ACK   <──────────────────────────────────               │
│  TCP ACK       ──────────────────────────────────>   1 RTT       │
│                                                                  │
│  TLS Hello     ──────────────────────────────────>               │
│  TLS Hello     <──────────────────────────────────               │
│  TLS Finished  ──────────────────────────────────>   2 RTT       │
│  TLS Finished  <──────────────────────────────────               │
│                                                                  │
│  HTTP Request  ──────────────────────────────────>   3 RTT       │
│  HTTP Response <──────────────────────────────────               │
└──────────────────────────────────────────────────────────────────┘

TCP + TLS 1.3: 2 RTT (TLS 1.3 is 1-RTT)

On 100ms RTT: 200-300ms before data flows

QUIC Solution

QUIC: 1 RTT (or 0 RTT for repeat visits)
┌──────────────────────────────────────────────────────────────────┐
│  QUIC Initial + TLS Hello ─────────────────────────>             │
│  QUIC Initial + TLS      <───────────────────────────            │
│  QUIC + Request          ─────────────────────────>   1 RTT      │
│  QUIC + Response         <───────────────────────────            │
└──────────────────────────────────────────────────────────────────┘

0-RTT resumption:
┌──────────────────────────────────────────────────────────────────┐
│  QUIC + TLS ticket + Request ───────────────────────> 0 RTT!     │
│  QUIC + Response            <─────────────────────────           │
└──────────────────────────────────────────────────────────────────┘

QUIC combines transport and crypto handshake.

Problem 3: Network Ossification

Middleboxes (firewalls, NATs, load balancers) inspect and sometimes modify traffic:

TCP extension deployment problem:

New TCP option added:
  1. RFC published
  2. OS kernels implement it
  3. Middlebox sees "unknown" option
  4. Middlebox strips it or drops packet!
  5. Feature doesn't work

Real examples:
  - TCP Fast Open: ~50% of paths don't work
  - ECN: Historically broken by many middleboxes
  - Multipath TCP: Often stripped

Result: TCP is effectively frozen.
        Can't add new features reliably.

QUIC Solution

QUIC encrypts everything:

UDP Header:  [Source Port] [Dest Port] [Length] [Checksum]
             ↑ Visible to middleboxes

QUIC Header: [Connection ID] [Packet Number] ...
             ↑ Encrypted (except initial packets)

QUIC Payload: [Encrypted frames]
              ↑ Encrypted

Middleboxes can see:
  - UDP ports
  - That it's QUIC (maybe)

Middleboxes cannot:
  - Inspect QUIC headers
  - Modify QUIC content
  - Apply TCP-specific rules

Result: QUIC can evolve without middlebox interference.

Problem 4: Connection Bound to IP Address

TCP connections are identified by:

(Source IP, Source Port, Destination IP, Destination Port)

Your phone on WiFi:
  192.168.1.100:52000 → 93.184.216.34:443

Phone moves to cellular:
  10.0.0.50:??? → 93.184.216.34:443

TCP: "That's a different connection!"
     Connection reset. Start over.

Mobile users experience this constantly:
  - WiFi to cellular handoff
  - Moving between cell towers
  - VPN connects/disconnects

QUIC Solution

QUIC connections identified by Connection ID:

Connection ID: 0x1A2B3C4D (random, opaque)

WiFi:    192.168.1.100 + CID 0x1A2B3C4D
Cellular: 10.0.0.50    + CID 0x1A2B3C4D

Server sees same Connection ID → Same connection!

Connection survives:
  - Network changes
  - IP address changes
  - NAT rebinding

Seamless for user. No reconnection needed.

Summary: QUIC’s Value Proposition

┌──────────────────────────────────────────────────────────────────┐
│           Problem             │        QUIC Solution             │
├───────────────────────────────┼──────────────────────────────────┤
│ TCP head-of-line blocking     │ Independent streams              │
│ High connection latency       │ 1-RTT, 0-RTT resumption          │
│ Protocol ossification         │ Encrypted, userspace impl.       │
│ Connections break on move     │ Connection ID migration          │
│ Unencrypted metadata          │ All headers encrypted            │
└───────────────────────────────┴──────────────────────────────────┘

These aren’t theoretical problems—they affect billions of users daily. QUIC provides solutions that TCP cannot, which is why it’s becoming the foundation for modern protocols.