QUIC

QUIC is a UDP-based, multiplexed, secure transport protocol that carries HTTP/3 and other application traffic. It combines independent streams, built-in TLS 1.3 encryption, and connection identifiers that keep sessions alive as networks change.

What QUIC is and why it exists

QUIC is a general-purpose transport protocol built on UDP that provides reliable, ordered, encrypted delivery across independent streams. It moves the work traditionally split between TCP and TLS into a single protocol designed for multiplexed traffic from the start.

The main reason QUIC exists is to remove transport-level head-of-line blocking. When multiple HTTP/2 streams share one TCP connection, a single lost packet stalls every stream until the loss is repaired, because TCP delivers one ordered byte stream and a gap blocks everything behind it. QUIC tracks streams inside the transport, so a lost packet affects only the streams whose data it carried. Other streams keep flowing.

Several design choices follow from that goal:

  • Built-in TLS 1.3. Encryption is part of the transport, not a separate layer added on top. The handshake travels inside QUIC itself, and nearly every byte after the first packet is encrypted.
  • Connection IDs. A connection is identified by an opaque Connection ID rather than the source and destination IP and port. This keeps a session bound to the same connection even when the underlying addresses change.
  • 0-RTT resumption. A client returning to a known server sends application data in its first flight, using cached session parameters, before the handshake finishes.
  • Connection migration. A session survives a change of network path, such as a phone moving from Wi-Fi to cellular, without starting over.

Relationship to HTTP/3 and UDP

QUIC is the transport layer that HTTP/3 runs on, and it runs on top of UDP. HTTP/3 keeps the same HTTP semantics as earlier versions, the same Methods, status codes, and Headers, and maps them onto QUIC streams instead of a TCP byte stream.

UDP provides only basic datagram delivery with no ordering, no retransmission, and no congestion control. QUIC supplies all of those on top of UDP, in userspace. Running over UDP rather than directly on IP lets QUIC deploy through existing networks, since routers, firewalls, and load balancers already forward UDP. It also sidesteps the slow pace of changing TCP, which lives in operating system kernels and middleboxes that rarely update. Each browser, server, and client library ships its own QUIC implementation, so improvements deploy at application speed.

The split of responsibilities is clean. QUIC handles transport: streams, loss recovery, congestion control, flow control, and encryption. HTTP/3 handles the HTTP mapping: framing requests and responses onto streams and compressing header fields with QPACK.

Streams and multiplexing

QUIC multiplexes data across independent streams, each an ordered sequence of bytes that the transport delivers and flow-controls on its own. A loss on one stream stalls only that stream. Every other stream continues without waiting.

Streams are identified by a 62-bit stream ID. The two least significant bits of the ID encode the stream type:

Bits Stream type
0x00 Client-initiated, bidirectional
0x01 Server-initiated, bidirectional
0x02 Client-initiated, unidirectional
0x03 Server-initiated, unidirectional

Bidirectional streams carry data in both directions. Unidirectional streams carry data one way. HTTP/3 maps each request and response pair onto its own client-initiated bidirectional stream, and uses unidirectional streams for control data and QPACK table updates.

Flow control operates at two levels. Each stream has its own limit on how much data the sender may send, and the connection has an aggregate limit across all streams. This pairing lets a receiver bound memory for any single stream while still capping total buffering for the whole connection.

Connection establishment and handshake

QUIC establishes a connection and its encryption in a single combined handshake. The transport setup and the TLS 1.3 handshake run together rather than as separate round trips, so a new connection reaches the point of sending application data in one round trip.

The two protocols cooperate closely. QUIC carries the TLS handshake messages inside CRYPTO frames, and TLS uses the reliable, ordered delivery QUIC provides. TLS produces the keys, and QUIC uses them to protect packets. The result is that almost the entire connection is encrypted, including most transport-level signaling.

A returning client uses 0-RTT resumption to send data even sooner. It reuses TLS session parameters cached from an earlier connection to encrypt application data in the first packet, before the server replies.

0-RTT replay risk

0-RTT data carries no replay protection. An attacker who captures a 0-RTT packet replays it to the server. Clients restrict 0-RTT to safe, idempotent requests, and servers respond with 425 Too Early to force a full handshake when a request must not be replayed. 0-RTT also lacks forward secrecy for the early data it protects.

To limit reflection and amplification attacks, a server must not send more than three times the number of bytes it has received from an address it has not yet validated. Initial packets are padded to at least 1,200 bytes, which keeps the amplification factor low and confirms the path supports a workable packet size.

Connection migration

QUIC keeps a connection alive when the network path changes, through a mechanism called connection migration. Because a connection is identified by its Connection ID rather than the source and destination IP and port, a change of address does not break the session.

The Connection ID is the key to this. TCP binds a connection to a 4-tuple of source IP, source port, destination IP, and destination port, so any change in that tuple ends the connection. QUIC carries a stable Connection ID in each packet, and the endpoints recognize the session by that value. When a client's address changes, packets still route to the right connection.

Each endpoint issues several Connection IDs to its peer. On migrating to a new path, the client switches to a fresh Connection ID from the pool, which prevents observers on the network from linking the old and new paths to the same session. The peer then validates the new path by sending a PATH_CHALLENGE frame and waiting for a matching PATH_RESPONSE before committing to it.

Only clients initiate migration. A server advertises a preferred address during the handshake to guide a client toward a more optimal endpoint, but it does not move the connection on its own. After a migration, congestion control resets and probes the new path's capacity, so throughput dips briefly while the connection settles. The same Connection ID mechanism also recovers from NAT rebinding, where a NAT assigns a new external port after a period of inactivity.

How QUIC differs from TCP plus TLS

QUIC replaces the combination of TCP and TLS with a single protocol that integrates transport and encryption. The practical differences show up in head-of-line blocking, handshake latency, connection identity, and where the protocol runs.

Property TCP + TLS QUIC
Layer location Kernel (TCP) plus library (TLS) Userspace over UDP
Multiplexing None in TCP, streams added by HTTP/2 above it Native, in the transport
Head-of-line blocking One lost packet stalls all streams Loss affects only the carrying streams
Handshake TCP handshake, then a separate TLS handshake Combined transport and TLS 1.3 handshake
New-connection setup Two or more round trips One round trip, or zero on resumption
Encryption scope TLS protects application data Transport and application data both encrypted
Connection identity 4-tuple of IP and port Opaque Connection ID
Path changes Connection breaks Connection migrates and continues

TCP delivers a single ordered byte stream, so multiplexing has to be layered above it, and a lost packet blocks everything queued behind it. QUIC builds streams into the transport, isolating loss to the affected streams. TCP and TLS each run their own handshake, while QUIC folds both into one. TCP ties a connection to a 4-tuple, while QUIC uses Connection IDs that let a session survive an address change. Because QUIC runs in userspace, congestion control algorithms and protocol fixes deploy with an application update rather than a kernel patch.

Example

A browser reaching a site over HTTP/3 first learns that QUIC is available, then opens a QUIC connection and sends the request on a stream. A common discovery path is the Alt-Svc response header returned over an existing HTTP/2 or HTTP/1.1 connection:

Alt-Svc: h3=":443"; ma=86400

This advertises HTTP/3 on UDP port 443, valid for one day. The ALPN token h3 identifies HTTP/3 over QUIC during the handshake.

After establishing the QUIC connection, the browser sends an HTTP/3 request on a client-initiated bidirectional stream. The request keeps familiar HTTP semantics, carried as QPACK-encoded header fields:

:method = GET
:scheme = https
:authority = www.example.re
:path = /index.html

If the device then switches from Wi-Fi to cellular mid-session, its IP address changes. Rather than reconnecting, QUIC migrates the connection: the client picks a new Connection ID and continues on the new path once a PATH_CHALLENGE and PATH_RESPONSE confirm it. The request stream and any others on the connection carry on without a fresh handshake.

See also

Last updated: June 5, 2026