Skip to content

Build1 publisher2 min readPublished

HTTP/2 gives a lossy mobile link one TCP connection to stall instead of six

A dev.to guide walks Laravel apps from HTTP/1.1 to HTTP/3 on nginx, and the part worth reading twice is its admission that the middle step can hurt, because one connection carrying 40 streams stalls on one lost packet.

The Engineer · Build desk

Illustration accompanying HTTP/2 gives a lossy mobile link one TCP connection to stall instead of six

What happened

  • HTTP/1.1 allows one outstanding request per connection, so browsers open six parallel TCP connections per host and a Laravel page with a bundle, CSS, fonts and images queues everything past the first six.
  • HTTP/2, from 2015, multiplexes every request as streams over a single TCP connection, compresses headers with HPACK, and lets a browser ask for 40 assets at once without queuing.
  • The dev.to guide states that on a bad connection HTTP/2 can occasionally perform worse than HTTP/1.1, whose six separate connections meant a lost packet stalled only a sixth of the downloads.
  • HTTP/3, standardised as RFC 9114 in 2022, keeps HTTP/2's semantics and swaps TCP for QUIC over UDP, with reliability, congestion control and TLS 1.3 folded into the protocol.
  • Cloudflare Radar data cited in the guide puts HTTP/3 at roughly 30% of human browser traffic on Cloudflare's network, and W3Techs has about a third of websites serving it.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • constraint HTTP/3 admits TLS 1.3 only, and HTTP/2 needs TLS because no browser ever implemented cleartext h2c, so a stack pinned below TLS 1.3 has a certificate and cipher job to finish before it has a protocol job.
  • capability Keying a connection on a connection ID instead of an IP and port pair lets a phone move from Wi-Fi to cellular without reconnecting, which no TCP-based deployment can offer at any amount of tuning.
  • decision Verification comes before the upgrade argument: a team that has never checked what its server negotiates may be debating QUIC while still shipping HTTP/1.1 to every visitor.

Six connections against 40 assets leaves 34 requests that cannot start until an earlier one finishes, and the busiest connection works through seven in series [1]. Each of those six pays its own TCP and TLS handshake first, two to three round trips before a byte of content moves [3].

TCP is the constraint underneath. It delivers one ordered byte sequence and knows nothing about streams, so one lost packet stalls every stream on that connection until the retransmission lands [5]. Six connections spread the damage: a lost packet takes out one of six, about 17% of what is in flight. One connection carries everything, so the same packet stalls all of it [2].

Under QUIC the streams are genuinely independent, and a lost packet delays only the file it carried [8]. The handshake combines transport and TLS into a single round trip, and a resumed session can put the first request inside the handshake itself at 0-RTT [9]. Against TCP plus TLS at two to three round trips, that saves one to two [3].

The measurement usually cited for this is Google's own QUIC deployment: an 8% reduction in mean search latency on desktop, a measurable improvement on mobile, and the biggest wins on the slowest connections, reported at SIGCOMM in 2017 [11]. Read it as a claim about Google search served from Google's edge. For the number to transfer to a Laravel app, the page would have to be bound by the same request count and loss behaviour a search response was, the traffic would have to include the slow connections where the gain concentrated, and the assets would have to be served by the host being upgraded. A Vite bundle plus a stylesheet, fonts and a dozen images is a different page shape.

There are two adoption paths in the guide. One is an nginx upgrade on Ubuntu 24.04 for HTTP/3 support, with a verification step for confirming HTTP/2 is actually negotiated [14]. The other is Cloudflare, which the guide says gets you HTTP/3 with zero origin changes [15]. With the origin untouched, QUIC terminates at the edge and the origin hop keeps whatever protocol it already spoke [4].

The guide bounds its own case. "On a fast office connection the three waterfalls look nearly identical. On a lossy mobile connection they look like three different websites," it says [17]. It also says the protocol under a Laravel app "deserves an afternoon of your time" [18]. The afternoon is the estimate I would check first, because the HTTP/3 half of it is a package upgrade on a live web server.

What to watch

  • Whether Cloudflare Radar's roughly 30% share of human browser traffic moves while W3Techs' count of sites serving HTTP/3 sits near a third.
  • An nginx build for Ubuntu 24.04 that ships QUIC support by default, removing the upgrade step the guide documents.
  • Published before-and-after waterfalls from real Laravel deployments on lossy links, instead of Google's 2017 search numbers.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories