HTTP/2, HTTP/3 (QUIC) and TLS 1.3: protocol-level speedups explained

HTTP/2, HTTP/3 and TLS 1.3 make websites faster by cutting the number of network round trips needed to connect and load a page. TLS 1.3 completes its handshake in one round trip instead of two, HTTP/2 sends many requests over a single connection, and HTTP/3 runs over QUIC, which combines the transport and encryption handshakes and avoids TCP's head-of-line blocking.
Because these gains are counted in round trips rather than milliseconds, they grow with distance. Saving two round trips is worth about 10 ms to a visitor next to your server, but 300–400 ms to a visitor on another continent, where light in fiber alone typically adds 150–200 ms to every round trip.
Why HTTP/1.1 is slow: head-of-line blocking and six connections
HTTP/1.1 handles one request at a time per connection. The next request on that connection waits until the previous response has fully arrived, a problem known as head-of-line blocking. Pipelining was meant to fix this but never worked reliably, so browsers keep it disabled.
To get parallelism, browsers open up to six connections per hostname. Each new connection pays for its own TCP and TLS handshakes and starts with a small congestion window, so it cannot use the available bandwidth right away. A page with 80 files still queues most of its requests. The old workarounds, such as domain sharding, image sprites and giant concatenated bundles, add DNS lookups and handshakes or hurt caching, and they work against HTTP/2.
HTTP/2: multiplexing, HPACK and the end of server push
HTTP/2 (RFC 9113) replaces text messages with binary frames and multiplexes many streams over one connection. Requests no longer queue behind each other, and a whole page can load over one handshake. Three features matter for speed:
- Multiplexing. Dozens of requests and responses travel interleaved on a single TCP connection, which also lets that connection's congestion window grow large.
- HPACK header compression. Repeated headers such as cookies, user agent and accept values are sent once, then referenced by index, so later requests carry a few bytes of headers instead of several hundred.
- Prioritization. Browsers signal which responses matter most. The original dependency tree was deprecated in favor of the simpler
priorityheader from RFC 9218, which HTTP/3 uses too.
Why browsers removed HTTP/2 server push
Server push let a server send files before the browser asked for them. In practice it often pushed files the browser already had in its cache, competed with more important responses for bandwidth, and was hard to tune. Measured gains were rare, so Chrome disabled push in 2022 and Firefox removed it in 2024. Its job now belongs to 103 Early Hints, covered below.
The weakness HTTP/2 inherits from TCP
TCP delivers bytes strictly in order. If one packet is lost, every stream on the connection waits for its retransmission, even streams whose data already arrived. On a clean wired link this rarely matters. On mobile or congested networks with 1–2% packet loss, one HTTP/2 connection can stall more often than six HTTP/1.1 connections.
HTTP/3 and QUIC: faster handshakes without TCP head-of-line blocking
HTTP/3 (RFC 9114) maps HTTP onto QUIC (RFC 9000), a transport protocol that runs over UDP and implements reliability, congestion control and streams itself. It changes four things:
- No transport-level head-of-line blocking. Each stream is delivered independently, so a lost packet delays only the stream it belongs to.
- A combined handshake. TLS 1.3 is built into QUIC, so the connection and its encryption are set up in a single round trip. Returning visitors can even send their first request immediately with 0-RTT.
- Connection migration. QUIC identifies connections by connection IDs instead of IP address and port, so a phone moving from Wi-Fi to mobile data can keep its connection instead of reconnecting.
- QPACK. A variant of HPACK designed for out-of-order delivery compresses headers.
Browsers learn that a site supports HTTP/3 from the Alt-Svc response header (or a DNS HTTPS record), so the very first connection to a site is usually HTTP/2 over TCP and later connections switch to HTTP/3. If UDP port 443 is blocked, as on some corporate networks, browsers silently fall back to TCP. That is why you keep HTTP/2 and TLS 1.3 over TCP enabled alongside HTTP/3.
TLS 1.3 vs TLS 1.2: handshakes, 0-RTT and the round-trip math
A full TLS 1.2 handshake takes two round trips: client and server first agree on parameters and send the certificate, then exchange keys and confirm. In TLS 1.3 (RFC 8446), the client sends its key share in the first message, so the server can answer with its own key share, certificate and confirmation in a single flight. TLS 1.3 also drops obsolete ciphers and RSA key exchange, so every connection gets forward secrecy. Browsers can shorten TLS 1.2 with False Start on well-configured servers, but TLS 1.3 makes one round trip the default.
Here is what that means before the first byte of HTML arrives on a brand-new connection, excluding DNS and server processing time:
| Connection setup | Handshake round trips | First byte after | At 20 ms RTT | At 180 ms RTT |
|---|---|---|---|---|
| TCP + TLS 1.2 | 3 | 4 RTT | 80 ms | 720 ms |
| TCP + TLS 1.3 | 2 | 3 RTT | 60 ms | 540 ms |
| TCP + TLS 1.3, 0-RTT resumption | 1 | 2 RTT | 40 ms | 360 ms |
| QUIC (HTTP/3) | 1 | 2 RTT | 40 ms | 360 ms |
| QUIC, 0-RTT resumption | 0 | 1 RTT | 20 ms | 180 ms |
A 180 ms round trip is typical between Seoul and a server in Virginia. Moving from TCP + TLS 1.2 to QUIC saves about 360 ms there before your server even starts working, and it saves it again for every new connection, including those to third-party domains.
0-RTT resumption and its replay caveat
A returning visitor's browser can resume a TLS 1.3 session with a pre-shared key and send its first request along with the handshake, as early data. That early data has no replay protection: an attacker who captures it can send it again. Only act on early data for idempotent requests such as a GET for a page. Pass a flag to your application, as in the nginx example below, and answer state-changing requests that arrive as early data with 425 Too Early, which makes the browser retry after the full handshake.
Certificate size, OCSP stapling and 103 Early Hints
Keep the certificate chain small
The server sends its certificate chain during the handshake. If the chain does not fit in the first flight, the handshake costs an extra round trip. TCP servers typically start with a 10-packet congestion window, about 14 KB. QUIC servers may send only three times the bytes received from the client until its address is validated, often around 3.6 KB at first.
- Use an ECDSA P-256 certificate. Its keys and signatures are a fraction of the size of RSA-2048 ones and cheaper for the server to compute. Keep an additional RSA certificate only for very old clients.
- Serve the leaf and intermediates only. Never include the root, and drop unneeded cross-signed intermediates.
- Enable TLS certificate compression where your server or CDN supports it; Chrome and Cloudflare do.
OCSP stapling still helps, but matters less
OCSP stapling lets your server attach a recent, CA-signed statement that its certificate has not been revoked, so browsers that check revocation do not have to contact the CA mid-handshake. Enable it when your certificate includes an OCSP URL. It matters less every year: Chrome does not make live OCSP requests, Firefox relies increasingly on its CRLite revocation lists, and Let's Encrypt shut down its OCSP service in 2025. Without an OCSP URL, nginx logs a warning and skips stapling.
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/example.com/chain.pem;
resolver 1.1.1.1 8.8.8.8 valid=300s;
103 Early Hints replaces server push
While your server builds the HTML, the connection sits idle. A 103 Early Hints response fills that gap with Link headers, so the browser can preconnect to other origins and preload critical CSS or fonts before the final response arrives. Chromium-based browsers act on preload and preconnect hints; support in other browsers is partial. Cloudflare can generate Early Hints automatically from the Link headers your pages already send.
HTTP/2 103
link: </css/site.css>; rel=preload; as=style
link: <https://img.example-cdn.com>; rel=preconnect
HTTP/2 200
content-type: text/html; charset=utf-8
link: </css/site.css>; rel=preload; as=style
Early Hints pay off most when your server takes a few hundred milliseconds to respond. Shortening that wait is the bigger win, as our guide to reducing TTFB explains.
How to enable HTTP/3 and TLS 1.3 on nginx and CDNs
On nginx, HTTP/3 needs version 1.25 or newer, built with the HTTP/3 module and a QUIC-capable TLS library. Add a QUIC listener next to the TCP one, advertise it with Alt-Svc, and open UDP port 443 in your firewall or cloud security group:
server {
listen 443 ssl;
listen 443 quic reuseport; # reuseport: once per address:port
http2 on;
http3 on;
server_name www.example.com;
ssl_certificate /etc/ssl/example.com/fullchain.pem;
ssl_certificate_key /etc/ssl/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_cache shared:SSL:10m;
ssl_early_data on; # 0-RTT: mind the replay caveat
add_header Alt-Svc 'h3=":443"; ma=86400' always;
location / {
proxy_set_header Early-Data $ssl_early_data; # "1" for 0-RTT requests
proxy_pass http://127.0.0.1:8080;
}
}
Keep TLS 1.2 for older clients and leave TLS 1.0 and 1.1 off. Apache httpd serves HTTP/2 through mod_http2 (Protocols h2 http/1.1) but has no built-in HTTP/3, so Apache sites usually get it from a CDN or a QUIC-capable proxy in front. Caddy enables HTTP/3 by default.
With a CDN, the edge terminates TCP, TLS and QUIC near the visitor, so each handshake costs a short round trip, while the CDN keeps warm connections to your origin. On Cloudflare, TLS 1.3 is on by default, and HTTP/3, 0-RTT and Early Hints are dashboard toggles; see Cloudflare's HTTP/3 documentation. CloudFront, Fastly and Akamai support HTTP/3 as well. Our guide to how a CDN works covers the rest.
How to verify HTTP/3 and TLS 1.3
# Does the server advertise HTTP/3?
curl -sI https://www.example.com | grep -i alt-svc
# alt-svc: h3=":443"; ma=86400
# Request over HTTP/3 (needs curl built with HTTP/3; --http3-only disables fallback)
curl -sI --http3 https://www.example.com | head -1
# HTTP/3 200
# Which TLS version does a TCP connection use?
curl -svo /dev/null https://www.example.com 2>&1 | grep "SSL connection"
# * SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256 ...
In Chrome DevTools, right-click the Network panel's column headers, enable Protocol and reload: h3 means HTTP/3 and h2 means HTTP/2. The first request after a cold start often shows h2, because the browser learns about HTTP/3 from Alt-Svc; reload to see h3.
Reading TCP and TLS times in the 8-region test
Run a free 8-region speed test and open the regional breakdown. Each region's first-visit timeline shows DNS, TCP, TLS and server wait as separate segments; hover a segment to see its time.
- TCP is the TCP handshake alone: about one round trip to whichever server terminates the connection, your origin or a CDN edge.
- TLS is the TLS handshake: about one round trip with TLS 1.3, two with a full TLS 1.2 handshake, plus key exchange and certificate checks in the browser, which typically add 10–20 ms.
- Server wait starts once the connection is ready: one more round trip plus your server's processing time.
Compare the segments in your far regions, where round trips dominate. TLS close to TCP means one-round-trip TLS 1.3; TLS around twice TCP points to TLS 1.2 or a certificate chain that overflows the first flight. TCP above 100 ms in several regions means visitors there connect to a distant origin, which a CDN cuts to a few milliseconds, as our guide to why websites are slow in other countries explains. The report flags "Connection setup is slow" when TCP plus TLS averages more than 250 ms.
Far regions gain the most from protocol upgrades. Moving from TLS 1.2 to TLS 1.3 saves one round trip: a few milliseconds in the origin region, but typically 150–250 ms on other continents. If a connection uses HTTP/3, its TCP segment drops to near zero, because Chromium reports the combined QUIC handshake as TLS time.
The repeat visit runs in a new browser process with a warm HTTP cache but no open connections, so it performs fresh handshakes without connection reuse or 0-RTT. Similar TCP and TLS times on both visits are normal; the repeat visit isolates caching. Our methodology explains how each timing is measured.
Frequently asked questions
Is HTTP/3 faster than HTTP/2?
Usually, especially on new connections and on lossy or mobile networks. HTTP/3 sets up transport and encryption in one round trip instead of two and avoids TCP head-of-line blocking, so the gains are largest for distant and mobile visitors. On a stable connection to a nearby server the difference is often small.
Do I need TLS 1.3 to use HTTP/3?
Yes. QUIC has TLS 1.3 built in, so every HTTP/3 connection uses it. Enable TLS 1.3 for TCP connections as well, because browsers fall back to HTTP/2 over TCP when UDP is blocked.
Why did browsers remove HTTP/2 server push?
Server push often sent files the browser already had cached, wasted bandwidth and was hard to configure well, so real-world gains were rare. Chrome disabled it in 2022 and Firefox removed it in 2024. 103 Early Hints with preload or preconnect links is the recommended replacement.
Is TLS 1.3 0-RTT safe to enable?
It is safe for idempotent requests such as GET, but early data can be replayed by an attacker. Only accept 0-RTT for requests that do not change state, and have your application reject logins, payments and form posts that arrive as early data.
How do I check if my website uses HTTP/3?
In Chrome DevTools, enable the Protocol column in the Network panel and reload the page: h3 means HTTP/3 and h2 means HTTP/2. From a terminal, run curl --http3 -I with your URL using a curl build that supports HTTP/3. The very first load often shows h2 because browsers learn about HTTP/3 from the Alt-Svc header.


