Ep #113: Network Protocols at Scale (Part 2): Why HTTP/3 Had to Abandon TCP
The evolution of the web, Head-of-Line blocking, and why Google rebuilt HTTP on top of UDP.
By Amit Raghuvanshi | The Architect’s Notebook
🗓️ Jun 2, 2026 · Deep Dive ·
1. HTTP/1.1 — The Bottleneck
In Part 1, we established the foundation: TCP provides reliable streams, but it is slow to start and heavy to manage. Now, let’s look at the Application Layer. HTTP runs on top of TCP. And the history of HTTP is really a story about fixing one fundamental architectural mistake — sequential request-response over a single connection — and then the knock-on problems that each fix introduced. Understanding why each version exists makes you a better infrastructure architect.
HTTP/1.1 — The Bottleneck
The problem: HTTP/1.1 is sequential on a single connection. Browsers work around this by opening 6-8 parallel TCP connections per domain, but each has its own handshake overhead and slow start.
System Design Impact of HTTP
Stateless by design — Each request is independent. This is what makes horizontal scaling possible (any server can handle any request).
Headers are verbose — Repeated headers (cookies, auth tokens, user-agent) on every request can waste significant bandwidth at scale.
Keep-Alive — Reuses TCP connections across requests. Critical for performance. Without it, every single HTTP request pays the TCP + TLS handshake cost.
HTTP/2: The Right Fix (With One Flaw)
HTTP/2 solved the sequential problem by introducing Multiplexing. Instead of opening 6 connections, the client opens one TCP connection. It chops up Request A, B, and C into tiny frames and interleaves them simultaneously over that single connection.
Key features:
Multiplexing — Multiple requests/responses on a single TCP connection
Header compression (HPACK) — Dramatically reduces header overhead
Server push — Server can proactively send resources (though rarely used in practice)
Binary framing — More efficient parsing than HTTP/1.1’s text format
The remaining problem: It introduced a catastrophic flaw hidden at the layer beneath it.. TCP’s head-of-line blocking. If one TCP packet is lost, ALL streams on that connection stall while TCP retransmits. This can make HTTP/2 slower than HTTP/1.1 on lossy networks.
2. The TCP Head-of-Line Blocking Problem
HTTP/2 solved application-layer blocking, but it exposed TCP Head-of-Line Blocking.
TCP guarantees strict, ordered delivery. It doesn’t know about HTTP/2 “streams”; it just sees a pipe of bytes. If a single TCP packet is lost on the network:
Packets 51, 52, and 53 arrive successfully at the server’s OS Kernel.
But because Packet 50 was lost, TCP refuses to give 51-53 to the application. It holds them in a buffer and waits for the client to retransmit Packet 50.
Because HTTP/2 puts all streams on one connection, a single dropped packet stalls every single active request.
Real Data Point: Google measured this internally. On a reliable corporate LAN, HTTP/2 is universally better. But on a mobile network with >2% packet loss, HTTP/2 is actually slower than HTTP/1.1, because HTTP/1.1’s 6 parallel connections fail independently, while HTTP/2’s single connection stalls entirely.
🔒 Subscribe to read how HTTP/3 & QUIC Fix This
We hit the limit of what TCP can do. So the industry threw it away. How do you get reliable delivery without Head-of-Line blocking? You build it yourself on top of UDP.
In the rest of this deep dive, we will cover:
QUIC & HTTP/3: How it works, why it uses UDP, and how it achieves 0-RTT connections.
Connection Migration: Why switching from WiFi to Cellular drops your TCP calls, but QUIC survives seamlessly.
The Latency Budget: A mathematical breakdown of where every millisecond goes in a network request.




