โš–๏ธ HTTP/1.1 vs /2 vs /3

The whole family on one page โ€” what changed at each step, and a straight answer on which version to run where.

The Master Comparison

DimensionHTTP/1.1HTTP/2HTTP/3
TransportTCPTCPQUIC / UDP
EncodingTextBinary framesBinary frames
MultiplexingโŒ (1 req/conn)โœ… (streams)โœ… (streams)
App-layer HOL blockingYes (ordered)NoNo
Transport HOL blockingPer-connectionYes (shared TCP)No (per-stream)
Header compressionNoneHPACKQPACK
EncryptionOptional (TLS)Optional, ~always TLSMandatory (TLS 1.3)
Handshake costTCP (+TLS)TCP + TLSFused, 1-RTT / 0-RTT
Connection migrationโŒโŒโœ… (Connection IDs)
Server pushโŒโœ… then deprecatedEffectively unused
Concurrency hack neededSharding / bundlingNoneNone

What Each Jump Actually Bought

flowchart LR A["HTTP/1.1
text ยท 1 req/conn"] -->|"binary framing
+ multiplexing"| B["HTTP/2
many streams / 1 TCP"] B -->|"ditch TCP
โ†’ QUIC on UDP"| C["HTTP/3
independent streams"]

Which Should You Run?

Short answer: offer HTTP/2 and HTTP/3 together behind your edge, with HTTP/1.1 as the universal fallback. You rarely choose one โ€” clients negotiate the best they can reach.
SituationBest fitWhy
Public web app / CDN edgeH3 + H2 fallbackMobile users benefit most from QUIC; H2 covers blocked-UDP networks
Internal service-to-serviceHTTP/2Stable low-loss links; simpler ops; native gRPC transport
Simple API, low volumeHTTP/1.1Trivially debuggable; multiplexing gains are marginal at low concurrency
Lossy / high-latency clientsHTTP/3Independent streams + 0-RTT + migration win exactly here
Legacy / restrictive middleboxesHTTP/1.1 or /2UDP may be throttled or blocked outright

Migration Gotchas

Don't carry HTTP/1.1 habits into HTTP/2+. Domain sharding, sprite sheets, and aggressive asset concatenation were workarounds for the 6-connection limit โ€” under multiplexing they hurt (more connections fight congestion control; huge bundles defeat fine-grained caching).
Server push is a dead end. If you built around it, migrate to <link rel="preload"> and 103 Early Hints โ€” both survive the version you're on and the ones you're moving to.
Real-world: in most stacks the version is a property of your load balancer / CDN, not your application code โ€” HTTP semantics are identical across versions, so your handlers don't change. You flip it on at the edge and measure tail latency (p99) on real client networks, where HTTP/3's advantages actually appear.

Key Takeaways

Bottom line: the three versions are one continuous fight against head-of-line blocking. Serve H2 and H3 at the edge, keep H1.1 as a floor, and drop the old concatenation/sharding tricks. For the payload inside these requests, continue to Serialization โ€” the format on the wire is the other half of protocol performance.