HTTP/2 and HTTP/3: what changed and how to enable them
HTTP/2 and HTTP/3 let a browser fetch many files at once and cope better with lost packets. What changed, how to check your site, and how to switch them on.
In this guide
Three versions in plain words
HTTP is the set of rules for asking for a file and getting an answer. The rules about what a request and an answer mean (methods, status codes, headers) have stayed the same. What changed between versions is how the messages are packed and sent.
| HTTP/1.1 | HTTP/2 | HTTP/3 | |
|---|---|---|---|
| Carried by | TCP | TCP | QUIC, which runs on UDP |
| Requests in flight | One per connection | Many on one connection | Many on one connection |
| Headers | Sent in full each time | Compressed | Compressed |
| A lost packet | Delays one connection | Delays every file on the connection | Delays only the file it belongs to |
| Setting up | A TCP handshake, then a TLS handshake | The same | QUIC builds the TLS handshake into its own, so fewer messages are needed |
HTTP/1.1 dates from 1997. Because it sends one request at a time on each connection, browsers open up to six connections to each host to get more done. HTTP/2 was standardized in 2015 and removed that limit: requests are multiplexed, which means many of them share one connection. HTTP/3 was standardized in 2022.
What problem each one solves
HTTP/2 solved waiting in line. A page with 70 files no longer has to queue them behind six connections. Headers such as cookies and the user agent are sent many times in HTTP/1.1, and HTTP/2 compresses them, which matters for pages with many small requests. It also lets the browser say which files are more important.
HTTP/3 solved the weakness HTTP/2 inherited from TCP. HTTP/2 puts everything on one TCP connection, and TCP delivers bytes in order. If one packet is lost, every file on that connection waits until it is sent again. QUIC runs over UDP and detects loss for each stream separately, so a lost packet stalls only the file that was in it. The effect is largest on poor or congested networks, such as a phone on a weak signal.
Neither protocol makes a large image smaller or removes a slow script. They make better use of the connection that is there.
How common they are
The 2024 Web Almanac looked at the main page document of the sites in its sample: about 21% to 22% were loaded over HTTP/1.1, 70% to 71% over HTTP/2 and 7% to 9% over HTTP/3 as it measured them. It adds that this undercounts HTTP/3, and that real support is closer to 30%. The reason is covered below. Across all requests, including those to other companies, 85% used HTTP/2 or HTTP/3.
CDNs drive this. Fewer than 4% of requests served by a CDN used HTTP/1.1, against up to 29% of requests that did not come through one. The Almanac points to smaller sites that run their own servers without a CDN as the ones most likely to be left behind.
How to check your site
- Chrome DevTools. Open the Network tab, right-click the column headers and add Protocol.
h2means HTTP/2,h3means HTTP/3 andhttp/1.1is the old version. - The Lighthouse report. The insight called Modern HTTP flags HTTP/1.1 requests, but only when six or more static files come from the same host and are not served by a service worker. It ignores tiny tracking images from other companies, and it estimates the time that HTTP/2 would save. The desktop test that Google's hosted tools run skips this insight, according to the Lighthouse source, so look at the mobile report.
- The command line. curl shows the version in the first line of its answer:
curl -sI --http2 https://example.com/ | head -n 1
curl -sI --http3 https://example.com/ | head -n 1The first should print HTTP/2 200. The second needs a curl built with HTTP/3 support. Its documentation says it tries HTTP/3 and falls back to earlier versions if the attempt fails or is slow, so a line that says HTTP/2 means the fallback happened.
- In the page. Paste this into the console after the page has loaded to list the files that did not use HTTP/2 or HTTP/3:
performance.getEntriesByType("resource")
.filter(e => e.nextHopProtocol && !["h2", "h3"].includes(e.nextHopProtocol))
.forEach(e => console.log(e.nextHopProtocol, e.name));Files from other hosts that do not send a Timing-Allow-Origin header report an empty protocol and are left out.
Why you see h2 on a first visit and h3 later
A browser does not try HTTP/3 on a host it has never used. Suppose it tried and the server did not support it. QUIC runs over UDP, so there is no instant fallback to HTTP/2 or HTTP/1.1 as there is with TCP. The browser would have to wait for the attempt to time out, which can take several seconds. So it only uses HTTP/3 when the server has said that it supports it. There are two ways to say so:
- The `Alt-Svc` header. A response over HTTP/2 or HTTP/1.1 carries a line such as
Alt-Svc: h3=":443"; ma=86400. It means HTTP/3 is available on port 443 for the next 86,400 seconds, which is 24 hours and is the default whenmais left out. The browser then uses HTTP/3 for later connections. The first visit is always over the older protocol. Browsers have understood this header since Chrome 52, Firefox 38 and Safari 17. - A DNS record. A DNS HTTPS record can announce HTTP/3 support before the first connection is made. It is newer and less widely supported.
A network that blocks UDP traffic also makes visitors fall back to HTTP/2. That still works, without the benefit.
How to turn them on
Ask your host or CDN first. On a CDN this is usually a switch. Some managed hosts have it on already, and if yours does not, the host can enable it. The protocol between the visitor and the CDN is independent of the one between the CDN and your server, so enabling it at the edge helps your visitors even when your own server is older.
If you run the server yourself:
- Apache has the module
mod_http2, available from version 2.4.17. Inside a secure virtual host, addProtocols h2 http/1.1. Apache's documentation warns that HTTP/2 uses more threads and more memory than HTTP/1.1, so busy sites should watch their resources. - Nginx needs to be built with the HTTP/2 module, which is not part of the default build. Then use
listen 443 ssl;withhttp2 on;, a directive available from version 1.25.1. - HTTP/3 on Nginx needs a separate module, available from version 1.25.0 and described in Nginx's own documentation as experimental. It needs a recent OpenSSL or one of the other supported TLS libraries. A minimal setup listens for QUIC and for TLS on the same port, and advertises HTTP/3:
server {
listen 443 quic reuseport;
listen 443 ssl;
http2 on;
add_header Alt-Svc 'h3=":443"; ma=86400';
# ssl_certificate and ssl_certificate_key as usual
}HTTP/3 uses UDP, so the firewall must allow UDP on that port as well as TCP. HTTP/3 works only over HTTPS, and a site that is not yet on HTTPS needs that first. See TLS and HTTPS speed.
What to stop doing
- Domain sharding. Spreading files over several host names to get more connections was a trick for HTTP/1.1. MDN now calls it deprecated and says it can hurt performance with HTTP/2.
- Merging everything into one file. Combining files and image sprites mattered because requests were expensive. They matter less now, though web.dev notes that larger files still compress better, so a few well-chosen bundles are fine. In the Speed Lab test of many small files, two pages with the same bytes finished 21 ms apart over HTTP/2 and 518 ms apart over HTTP/1.1. See also page weight and requests.
- HTTP/2 Server Push. It let the server send files before the browser asked, and it was hard to get right. Chrome turned it off by default in version 106, after it was found on only about 1.25% of HTTP/2 sites. Use a
preloadhint or103 Early Hintsinstead. See resource hints.
Things that can go wrong
- Stricter header rules. HTTP/2 is less forgiving than HTTP/1.1. web.dev notes that headers with uppercase letters or characters outside ASCII can start to cause errors after a switch, and the browser then shows
ERR_HTTP2_PROTOCOL_ERROR. Test the pages before you switch production. - More load on the server. HTTP/2 and HTTP/3 keep more state and, for HTTP/3, use more processor time. The Almanac mentions the extra CPU cost of HTTP/3.
- Files from other hosts. Your own settings do not change how other companies serve their scripts. A page can be fully on HTTP/2 and still wait for a slow third party.
- Expecting a Core Web Vital to move. Newer protocols are not a metric. They help First Contentful Paint and Largest Contentful Paint indirectly, when the page was held back by connections and lost packets.
Check your own page
Run the free audit and look for the Modern HTTP insight on the mobile report. Then confirm in the Network panel that the page document and the stylesheets and scripts show h2 or h3. If they show http/1.1, ask your host or CDN to enable HTTP/2, because that is usually a quick change with no work on the site.
Sources
- Evolution of HTTP on MDN: HTTP/1.1, HTTP/2 and HTTP/3, and the six connections.
- HTTP/2, HTTP/3 and QUIC in the MDN glossary.
- Alt-Svc and nextHopProtocol on MDN.
- HTTP chapter, Web Almanac 2024: adoption, and how HTTP/3 is discovered.
- Removing HTTP/2 Server Push from Chrome on Chrome for Developers.
- Content delivery networks (CDNs) on web.dev: HTTP/2 and HTTP/3 behavior at a CDN.
Start here
Free website audit
Live Google data for any public page: mobile and desktop.
Mobile + desktop · Lighthouse lab test · Real-user Chrome data when Google has it
Rather have this done for you? Speed optimization · Book a call