HTTP/3

HTTP/3 is the latest major revision of the HyperText Transfer Protocol, published in June 2022 as RFC 9114. The protocol changes the underlying transport from TCP to QUIC (RFC 9000), a UDP-based transport with built-in TLS 1.3 encryption and independent stream delivery.

The HTTP semantics (Methods, status codes, Headers) remain identical to HTTP/2 and HTTP/1.1. What changes is the transport layer: QUIC eliminates TCP's head-of-line blocking, reduces connection setup latency, and enables connection migration across networks.

Baseline: Newly available

Supported in all major browsers. webstatus.dev

QUIC origins

Google began developing QUIC ("Quick UDP Internet Connections") in 2012, designed by Jim Roskind. Chrome shipped an experimental QUIC implementation in 2013. The original Google QUIC (gQUIC) used a custom cryptographic handshake and fused transport, crypto, and HTTP into a single monolithic design.

The IETF QUIC Working Group was chartered in October 2016 to standardize the protocol. The IETF version diverged significantly from gQUIC: standard TLS 1.3 replaced the custom handshake, the wire format was redesigned, and the architecture became modular, with separate RFCs for transport, TLS integration, loss detection, and HTTP mapping. In October 2018, the HTTP-over-QUIC mapping was officially named HTTP/3.

The core QUIC RFCs (9000–9002) were published in May 2021. HTTP/3 (RFC 9114) and QPACK (RFC 9204) followed in June 2022.

Why QUIC replaces TCP

TCP was not designed for multiplexed HTTP. Two fundamental problems drove the need for a new transport:

Head-of-line blocking

HTTP/2 multiplexes streams over a single TCP connection. TCP guarantees in-order byte delivery: if one packet is lost, every subsequent packet waits in the kernel buffer until the lost packet is retransmitted. A single lost packet stalls all streams, regardless of which stream the lost data belonged to.

QUIC implements stream awareness at the transport layer. Each stream is an independent, ordered byte sequence. A lost packet affects only the streams whose data was in the lost packet. All other streams continue processing without delay.

HTTP/2 vs QUIC{: loading="lazy" }

TCP ossification

Updating TCP is impractical at scale. The protocol is implemented in operating system kernels, firmware, and network middleboxes rarely receiving updates. Deploying changes to TCP behavior takes years or decades. QUIC runs in userspace over UDP, making updates deployable as application-level changes without requiring kernel or middlebox modifications.

QUIC is not part of the operating system's networking stack. Browsers, servers, and HTTP client libraries each ship their own QUIC implementation. This means more independent codebases, but also means bug fixes and protocol improvements deploy at application speed rather than OS update speed.

Connection setup

TCP establishes a connection with a three-way handshake (SYN, SYN-ACK, ACK). Each side must confirm the other's sequence numbers and verify bidirectional communication works. This exchange exists to prevent stale packets from earlier connections from being misinterpreted as new data. TLS then adds its own handshake on top.

QUIC combines transport and cryptographic handshakes into a single operation. The connection is both established and encrypted in one flight.

Scenario Round trips
TCP + TLS 1.2 (new) 3 RTT
TCP + TLS 1.3 (new) 2 RTT
TCP + TLS 1.3 (resumed) 2 RTT
QUIC (new connection) 1 RTT
QUIC (0-RTT resumption) 0 RTT

With TLS 1.2, the first HTTP response arrives after four round trips: one for TCP, two for TLS key exchange, and one for the HTTP request. TLS 1.3 reduces the TLS portion to one round trip. HTTP/3 eliminates the TCP handshake entirely. QUIC's combined handshake plus the HTTP request takes two round trips total, or one on resumed connections.

TCP vs QUIC{: loading="lazy" }

0-RTT resumption

When a client has previously connected to a server, QUIC supports Zero Round Trip Time Resumption (0-RTT). The client uses cached TLS 1.3 session parameters to encrypt and send application data in the first packet, before the server responds.

Replay risk

0-RTT provides no replay protection. An attacker who captures 0-RTT data replays the captured packets to the server. Clients must send only safe, idempotent requests in 0-RTT. Servers respond with 425 Too Early to force a full handshake retry. 0-RTT also lacks forward secrecy: if the session resumption key is compromised, early data is exposed.

Anti-amplification limit

A server responding to an unverified source address must not send more than three times the data the server has received. This limits reflection and amplification attacks. The initial packet must be padded to a minimum of 1,200 bytes to keep the amplification factor low.

Streams and frames

Stream types

QUIC identifies streams by 62-bit stream IDs. The two least significant bits encode the stream type:

Bits Type
0x00 Client-initiated bidirectional
0x01 Server-initiated bidirectional
0x02 Client-initiated unidirectional
0x03 Server-initiated unidirectional

HTTP/3 maps HTTP requests onto client-initiated bidirectional streams. Each request-response pair gets its own stream. Servers are expected to allow at least 100 concurrent request streams. Four types of unidirectional streams carry supporting data:

  • Control stream (type 0x00): one per peer, carries connection-level SETTINGS and GOAWAY frames. The SETTINGS frame must be the first frame sent. Closing a control stream is a connection error (H3_CLOSED_CRITICAL_STREAM).
  • Push stream (type 0x01): server-initiated, carries a pushed response (rarely used in practice)
  • QPACK encoder stream: carries dynamic table updates from encoder to decoder
  • QPACK decoder stream: carries acknowledgments from decoder to encoder

Each endpoint must allow the peer to create at least three unidirectional streams (control, encoder, decoder) with a minimum of 1,024 bytes flow-control credit each.

Frame types

HTTP/3 defines its own frame types, distinct from HTTP/2. Each frame is encoded as a variable-length integer type, a variable-length integer length, and a payload.

Frame Type Purpose
DATA 0x00 Request or response body
HEADERS 0x01 QPACK-encoded header fields
CANCEL_PUSH 0x03 Cancels a server push
SETTINGS 0x04 Connection configuration
PUSH_PROMISE 0x05 Server push notification
GOAWAY 0x06 Graceful connection shutdown
MAX_PUSH_ID 0x07 Limits server push stream IDs

HTTP/2 frame types like PRIORITY, RST_STREAM, PING, WINDOW_UPDATE, and CONTINUATION have no HTTP/3 equivalents. QUIC handles prioritization, stream cancellation, keepalive, and flow control at the transport layer.

Differences from HTTP/2

HTTP/3 does not support the HTTP Upgrade mechanism or the 101 Switching Protocols status code. The Transfer-Encoding header must not be used. QUIC's stream framing handles message delimiting. All header field names must be lowercase before encoding.

QPACK header compression

HTTP/3 uses QPACK (RFC 9204) for header compression, replacing HPACK used by HTTP/2. HPACK depends on TCP's in-order delivery to keep encoder and decoder tables synchronized, a requirement incompatible with QUIC's out-of-order stream delivery.

Aspect HPACK (HTTP/2) QPACK (HTTP/3)
Static table 61 entries 99 entries
Ordering Requires in-order delivery Works out of order
Table updates Inline in header blocks Separate encoder stream
Acknowledgment Implicit (TCP ordering) Explicit decoder stream

QPACK uses dedicated encoder and decoder streams (unidirectional) to decouple compression state updates from request and response data. This prevents header compression from reintroducing head-of-line blocking. The tradeoff is slightly lower compression efficiency compared to HPACK.

Connection migration

QUIC identifies connections using Connection IDs (CIDs) rather than the traditional TCP 4-tuple of source IP, source port, destination IP, and destination port. When a device moves from one network to another (such as switching from cellular to Wi-Fi), the IP address changes, but the CID keeps the connection alive.

Each connection has multiple CIDs known to both sides. When migrating to a new network, the client switches to a different CID from the pool. This prevents passive observers from correlating the old and new network paths. The server and client know the connection is the same, but the networks in between do not. The peer validates the new path by sending a PATH_CHALLENGE frame and waiting for a PATH_RESPONSE.

After migration, the congestion control algorithm restarts. The connection is maintained, but throughput drops momentarily while the algorithm probes the new network's capacity. QUIC also recovers from NAT rebinding (when a NAT assigns a new port after inactivity) using the same CID-based mechanism.

Connection migration matters most for mobile devices frequently switching between cellular and Wi-Fi, and in environments with rapid handoffs between cell towers (trains, stadiums, dense urban areas). Only clients initiate migration. Servers advertise a preferred address (RFC 9000 Section 9.6) to guide clients toward a more optimal endpoint after the handshake.

Connection coalescing

The ORIGIN frame (RFC 9412) allows a server to indicate which origins are available on an existing connection. A client seeing an ORIGIN frame listing multiple domains reuses the same QUIC connection for all of them, avoiding separate DNS lookups and handshakes. Chrome data shows roughly 20% of HTTP/3 connections are unnecessary due to IP mismatch issues ORIGIN frames resolve.

Congestion control

QUIC provides generic signals for congestion control, allowing the sender to choose its own algorithm. RFC 9002 specifies loss detection and congestion control for QUIC, using a NewReno-like baseline adapted for QUIC's encrypted headers and multiple packet number spaces.

In practice, implementations use more advanced algorithms:

  • CUBIC: uses a cubic function for window growth, handles high-bandwidth long-distance links better than NewReno
  • BBR (Bottleneck Bandwidth and Round-trip): developed by Google, estimates available bandwidth and minimum RTT rather than relying solely on packet loss signals

Because QUIC runs in userspace, swapping congestion control algorithms requires only an application update rather than a kernel patch. This makes QUIC a platform for rapid experimentation with algorithms tuned for specific environments: mobile, satellite, low-power, or long distance networks.

Per-connection, not per-stream

Congestion control in QUIC operates at the connection level. A lost packet triggers the congestion controller for the entire connection, even though only the affected stream's data delivery is blocked. The improvement over TCP is in data reassembly, not in congestion response.

Performance

Where HTTP/3 is faster

On lossy or high-latency networks (mobile, satellite, intercontinental links), independent stream delivery prevents the cascade stalling affecting HTTP/2 over TCP. The 0-RTT and 1-RTT handshakes save significant time on new connections. Connection migration prevents costly reconnection cycles when devices switch networks.

Google reported a 14% speed improvement for the slowest 10% of users. Fastly and Wix reported an 18–33% improvement in time to first byte.

The biggest gains go to the worst connections. HTTP/3 raises the performance floor. On a fast fiber connection, the difference is negligible, but on a weak mobile signal in a congested environment, HTTP/3 makes a measurable difference.

CPU overhead

QUIC runs in userspace rather than the kernel. UDP has historically received less hardware and kernel optimization than TCP. Research shows significantly more syscalls for a QUIC download compared to the same transfer over HTTP/2 with TCP. On fast, low-loss networks with ample bandwidth, this overhead means HTTP/3 transfers take more CPU time than equivalent HTTP/2 transfers.

Kernel-level optimizations are narrowing this gap. UDP Generic Segmentation Offload (GSO) and Generic Receive Offload (GRO) reduce per-packet overhead. Kernel bypass techniques like io_uring and DPDK improve throughput further.

Discovery

A browser connecting to a server for the first time has no way to know whether HTTP/3 is supported. The first request goes over HTTP/2 (or HTTP/1.1). Two mechanisms allow the server to advertise HTTP/3 for subsequent connections:

Alt-Svc header

A server advertises HTTP/3 support via the Alt-Svc response header on an existing HTTP/1.1 or HTTP/2 connection:

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

This tells the client HTTP/3 is available on UDP port 443 and the information remains valid for one day. After seeing this header, the browser sets up a QUIC connection for subsequent requests. The first visit always goes over HTTP/2.

SVCB and HTTPS DNS records

RFC 9460 defines the SVCB (Service Binding) DNS record type, a general-purpose mechanism for advertising service parameters directly in DNS. The HTTPS record type is a SVCB-compatible alias specific to HTTPS origins. For HTTP/3 discovery, the HTTPS record advertises supported ALPN protocols:

example.re 3600 IN HTTPS 1 . alpn="h3,h2"

This enables HTTP/3 on the first visit, without requiring a prior HTTP connection. The DNS response arrives during the address lookup already in progress. The record supports IP address hints and multiple prioritized endpoints:

example.re 3600 IN HTTPS 1 . alpn="h3,h2"
    ipv4hint="192.0.2.1" ipv6hint="2001:db8::1"

Fallback behavior

Browsers typically race a QUIC handshake against a TCP handshake in parallel. If QUIC responds within a short window (around 300–500ms), the browser uses HTTP/3. If QUIC fails, the TCP connection takes over transparently.

UDP blocking

An estimated 3–5% of networks block UDP traffic except for essential services like DNS. Corporate firewalls are the most common cause. When UDP is blocked, HTTP/3 is unavailable and the browser falls back to HTTP/2 over TCP automatically.

Security

QUIC integrates TLS 1.3 directly into the transport. Encryption is mandatory and covers the entire protocol with no unencrypted mode. The only plaintext fields in a QUIC packet are the version, Connection IDs (needed for routing before decryption), and a few signaling bits. Compared to HTTP/2 over TLS 1.3, HTTP/3 encrypts more of the connection. Encryption begins earlier in the handshake process and covers QUIC transport headers.

TLS 1.3 as enforced by QUIC eliminates weak cipher suites, requires perfect forward secrecy in all cipher suites, and includes downgrade detection.

This built-in encryption simplifies the connection process compared to TCP + TLS layering. Middleboxes such as firewalls and load balancers cannot inspect QUIC packet contents, which improves privacy but limits network-level traffic monitoring and analysis.

Ossification resistance

QUIC v2 (RFC 9369) exists primarily to exercise the version negotiation framework and prevent middleboxes from hardcoding assumptions about QUIC packet formats, the same kind of ossification making TCP difficult to update.

Adoption

Chrome enabled HTTP/3 by default and has continued expanding QUIC capabilities. Chrome enabled the ORIGIN frame (RFC 9412) and the server's preferred address by default, reducing connection overhead and latency further.

HTTP/3 is supported by all major browsers (Chrome, Firefox, Safari, and Edge) and runs on a significant share of global web traffic. Cloudflare reports roughly 21% of its requests use HTTP/3, behind HTTP/2 at 50% but closing in on HTTP/1.1 at 29%. HTTP/3 traffic is indicated by the ALPN token h3 during the QUIC handshake.

Major CDN providers (including Cloudflare, Google Cloud, AWS CloudFront, Fastly, and Akamai) support HTTP/3. On the server side, LiteSpeed was the first to ship production-grade HTTP/3 support, followed by Caddy (enabled by default), Nginx, IIS (Windows Server 2022), and HAProxy. Apache httpd does not yet support HTTP/3.

The majority of HTTP/3 traffic flows through CDN infrastructure. Discovery through Alt-Svc headers and HTTPS DNS records means adoption is largely transparent to end users.

Server configuration

Enabling HTTP/3 requires listening on UDP in addition to TCP, and advertising support through the Alt-Svc header. Most servers keep HTTP/2 and HTTP/1.1 on TCP as fallback.

Nginx

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    listen 443 quic;
    listen [::]:443 quic;
    http2 on;

    ssl_certificate     /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    add_header Alt-Svc 'h3=":443"; ma=86400';
}

The quic parameter on the listen directive enables QUIC/HTTP/3 on UDP. The Alt-Svc header is required for browsers to discover HTTP/3 support on subsequent visits.

Caddy

Caddy enables HTTP/3 by default with automatic TLS. No additional configuration is needed:

example.re {
    # HTTP/3 is on by default
}

Traefik

# docker-compose.yaml
services:
  traefik:
    image: traefik:3
    command:
      - "--entryPoints.https.address=:443"
      - "--entryPoints.https.http3=true"
    ports:
      - "443:443/tcp"
      - "443:443/udp"

Both TCP and UDP must be published on the same port.

LiteSpeed

LiteSpeed enables HTTP/3 through the admin console under Listeners > SSL > Enable HTTP3/QUIC. OpenLiteSpeed supports HTTP/3 through its configuration file:

listener https {
    secure 1
    enableQuic 1
}

Firewall requirements

HTTP/3 requires UDP port 443 to be open. Servers listening on TCP 443 for HTTP/2 must also allow inbound UDP 443 for QUIC traffic. Load balancers and reverse proxies need UDP support or passthrough configured.

Testing HTTP/3

Browser DevTools

Open the Network tab, right-click the column headers, and enable Protocol. HTTP/3 connections show as h3.

curl

curl supports HTTP/3 when built with an HTTP/3- capable TLS backend (such as ngtcp2 + nghttp3, or quiche):

curl --http3 -I https://example.re

Use --http3-only to force HTTP/3 without TCP fallback. The response headers include alt-svc if the server advertises HTTP/3 support.

Online tools

  • http3.net: tests HTTP/3 support via real QUIC connections, parses Alt-Svc for protocol versions (h3, h3-29), port, and cache duration, and shows per-hop protocol versions across redirect chains

Verifying Alt-Svc

A quick check for HTTP/3 advertisement over an existing HTTP/2 or HTTP/1.1 connection:

curl -sI https://example.re | grep -i alt-svc

If the response includes h3=":443", the server supports HTTP/3.

QUIC beyond HTTP

QUIC is a general-purpose transport protocol, not specific to HTTP. Other protocols are adopting QUIC as their transport:

  • DNS over QUIC (DoQ, RFC 9250) encrypted DNS resolution over QUIC, an alternative to DNS over HTTPS and DNS over TLS
  • WebTransport: a web API for bidirectional client-server communication over QUIC and HTTP/2, designed for latency-sensitive applications like gaming and live Streaming
  • SSH over QUIC: experimental implementations exist, using QUIC to improve SSH performance on lossy networks

Takeaway

HTTP/3 addresses the fundamental transport-level limitations of HTTP/2 by replacing TCP with QUIC. Independent stream delivery eliminates head-of-line blocking. Built-in TLS 1.3 encryption simplifies connection security. Connection migration maintains sessions across network changes. The largest performance gains go to the worst connections. HTTP/3 raises the performance floor for mobile, satellite, and congested networks while maintaining unchanged HTTP semantics.

See also

Last updated: March 9, 2026