I work on OnePassApps, the team behind app.onepassapps.com, so this is our own site's own transport behaviour. Everything below was measured today, 10 November 2026, from one server over plain HTTPS - signed out, no browser session, no cookies, no JavaScript.

We have already written about the header set our pages send, the cache tiers, the edge, the method contract and the compression contract, and about the handshake underneath all of it. None of those posts changed the HTTP version and left everything else alone. This one does: every URL was fetched twice, once over HTTP/2 and once over HTTP/1.1, and the two answers were compared name by name.

What I measured

  • The 56 URLs in our own sitemap.xml, fetched once over HTTP/2 and once over HTTP/1.1 - 112 requests.
  • Six routes - the home page, /guides, /studios/image, /apps/movie-tracker and two API routes - fetched three times per protocol, 36 requests, to read the raw header names off the wire.
  • Four of those routes fetched five times per protocol, 40 requests, to check that the header set does not drift from request to request.

The table

Route HTTP/2 status HTTP/1.1 status Body bytes, both Header names over HTTP/2 Header names over HTTP/1.1
/ 200 200 24,644 19 21
/guides 200 200 61,393 19 21
/studios/image 200 200 16,865 19 21
/apps/movie-tracker 200 200 18,944 19 21
api.onepassapps.com/api/products 200 200 15,650 29 31
api.onepassapps.com/api/runtime 200 200 471 30 31

The document bytes are what arrived on the wire. No Accept-Encoding was sent, so nothing was compressed, which keeps the comparison literal.

The two answers are the same answer

Across all 56 URLs, over both protocols, every response was 200. The body length was identical between the two protocols on 56 of 56 - not one URL came back a byte longer or a byte shorter over HTTP/1.1 than it did over HTTP/2. On the six sampled routes the byte counts did not move at all across three requests per protocol: 24,644 every time on the home page, 61,393 every time on the guides, 471 every time on /api/runtime.

The document length on this host is not a fixed number for all time - a build moves it - but it did not move at all during this measurement. On the six sampled routes the byte counts were identical on every request, and the same was true of the length on all 56 URLs. The bytes inside a document are a different matter: we have already written about the per-request key our pages carry, so the two answers here were compared by length and by header name, not by content.

The two names that disappear

The header count is the only thing that changes, and it changes by a rule rather than by accident. Over HTTP/2 every page carried 19 header names. Over HTTP/1.1 the same page carried 21. The two extra names on the HTTP/1.1 answer were exactly Transfer-Encoding and Connection.

That is the connection itself being described: HTTP/1.1 has a transfer framing and a connection to keep alive, so it says so in headers. HTTP/2 has neither - one multiplexed stream carries the message and the framing is the frame - so both names are gone rather than restated. The API host tells the same story with one name missing instead of two: /api/runtime carries content-length: 471 under both protocols, so it never needed Transfer-Encoding, and only Connection came back on the HTTP/1.1 answer (30 names over HTTP/2, 31 over HTTP/1.1). /api/products, which is chunked, lost both.

Header names also change shape. Over HTTP/2 all 19 names arrived lower-case. Over HTTP/1.1 the same names arrived in their usual mixed case, with Connection and Transfer-Encoding capitalised.

Alt-Svc is the same on both

Every response on both hosts and both protocols carried Alt-Svc: h3=":443"; ma=86400. The advertisement is identical whichever protocol asked for it.

We are not claiming HTTP/3 works here. We had no HTTP/3 client, so this is an advertisement we read, not a protocol we exercised - the same limit we stated when we wrote about the handshake and the cipher underneath it.

Vary does not depend on the protocol either

Vary is where a server records which request headers changed the answer, so it is worth checking that it does not quietly change with the protocol.

On /api/products it read Accept-Encoding, Origin under both protocols, on all five requests each. On /api/runtime it read Origin under both protocols, on all five requests each. On the home page and on /guides there is no Vary at all under either protocol. Five requests per protocol per route, and the value never moved.

What this does not show

One build, one day, one machine, one network path, one region, plain HTTPS, signed out, no cookies, no JavaScript, no browser. The requests were made one at a time, so the time-to-first-byte numbers we saw - a mean of 0.119 seconds over HTTP/2 and 0.118 seconds over HTTP/1.1 across the 56 URLs - are sequential single-request timings on a shared path, not a benchmark, and the two numbers are far too close to call a winner. We did not test an HTTP/2 cleartext upgrade, did not open a browser and did not watch a real page load. We did not send Accept-Encoding, so nothing here says what the site does with compression.

Try it yourself

Every app and studio runs in your browser tab, and every one of them is listed here: the OnePassApps home page

Each app and studio also has a plain-language guide with its limits and its tool list: the OnePassApps guides