How HTTP Works

Comparison

HTTP/1.1 vs HTTP/2

Compare HTTP/1.1 and HTTP/2. Understand multiplexing, header compression, server push, and when upgrading to HTTP/2 actually improves performance.

Bottom line: HTTP/2 keeps HTTP semantics but changes transport behavior significantly: multiplexing replaces many HTTP/1.1 connection workarounds, and the migration question is usually about performance tradeoffs, not application semantics.

By How HTTP WorksReview process
HTTP/1.1
vs
HTTP/2

TL;DR: HTTP/2 keeps HTTP semantics but changes transport behavior significantly: multiplexing replaces many HTTP/1.1 connection workarounds, and the migration question is usually about performance tradeoffs, not application semantics.

The Practical Question

Most teams are not deciding whether they like binary frames more than text. They are deciding whether old HTTP/1.1 performance habits still make sense.

The short answer is usually no.

The Core Difference

HTTP/1.1 and HTTP/2 keep the same HTTP semantics: methods, headers, status codes, and bodies still mean the same things. The big change is in how those messages move over the connection.

HTTP/1.1 uses a text-based protocol. Each request/response is a sequence of human-readable lines. Each connection handles one request at a time; HTTP/1.1 pipelining exists in RFC 9112 but is disabled in browsers because of head-of-line blocking and broken proxies.

HTTP/2 uses a binary framing layer. Messages are split into frames and multiplexed over a single connection. Multiple requests and responses can be in-flight simultaneously without blocking each other.

Key Differences

FeatureHTTP/1.1HTTP/2
Protocol formatTextBinary frames
MultiplexingNo (one request per connection)Yes (multiple streams)
Header compressionNone (plain text)HPACK
Server pushNoDefined in RFC 9113, but removed from Chrome 106 and effectively dead
Connection reuseKeep-Alive (limited)Single connection per origin
TLS requiredNoNo (spec), Yes (browsers)
Head-of-line blockingHTTP + TCP levelTCP level only

Multiplexing

The biggest practical improvement in HTTP/2 is multiplexing. In HTTP/1.1, browsers open up to 6 parallel TCP connections per host to work around the one-request-per-connection limit. Each connection has its own TLS handshake overhead.

HTTP/2 opens a single connection per origin and sends all requests as independent streams over it. Streams are interleaved at the frame level — a slow response on stream 3 does not block stream 5.

This makes HTTP/1.1 performance tricks like domain sharding and request bundling unnecessary and counterproductive.

Header Compression

HTTP/1.1 sends full headers on every request. For a page with 50 resources, the browser sends the same Cookie, User-Agent, Accept-Encoding, and Authorization headers 50 times.

HTTP/2 HPACK compression maintains a dynamic table of previously seen headers. Repeated headers are sent as a single index byte instead of the full string. The gain is largest for requests with big, repeated Cookie and Authorization values. HPACK is deliberately designed to resist the CRIME-style compression attacks that broke TLS-level header compression.

Migration Considerations

HTTP/2 is negotiated via ALPN during the TLS handshake — no URL changes, no code changes for most applications. Clients that don’t support HTTP/2 automatically fall back to HTTP/1.1.

What to stop doing when moving to HTTP/2:

What still matters:

What This Means In Practice

If your frontend build strategy still reflects old HTTP/1.1 bottlenecks, HTTP/2 is often a reason to simplify rather than add more bundling and sharding tricks. The protocol upgrade does not fix bad caching or oversized assets, but it does remove some of the transport pain those old workarounds were compensating for.

HTTP/3

HTTP/3 (RFC 9114) runs the same semantics over QUIC (RFC 9000) on UDP, which removes TCP-level head-of-line blocking: a lost packet stalls only the stream it belongs to. QUIC integrates TLS 1.3 and can resume with 0-RTT, which is replayable and should be limited to safe requests. Browsers discover it through the Alt-Svc: h3=":443" response header or an HTTPS DNS record, and fall back to HTTP/2 when UDP/443 is blocked. All major browsers and CDNs (Cloudflare, CloudFront, Fastly) support it. See the HTTP/3 and QUIC guide for setup and verification.

Enable and verify

nginx 1.25.1 and later deprecated the http2 flag on listen; use the separate directive:

server {
    listen 443 ssl;
    http2 on;
    server_name example.com;
}

Older configs with listen 443 ssl http2; still work but log a deprecation warning. Check what a server negotiates:

curl -sI --http2 https://example.com | head -1     # HTTP/2 200
curl -sI --http1.1 https://example.com | head -1   # HTTP/1.1 200 OK
curl -sI --http3 https://example.com | head -1     # needs a curl built with HTTP/3

curl -sv prints the ALPN result (ALPN: server accepted h2) and Chrome DevTools shows it in the Protocol column (h2, h3).

FAQ

Does HTTP/2 require HTTPS?

Not by the spec, but in practice yes. All major browsers only implement HTTP/2 over TLS (h2). The plaintext version (h2c) exists in the spec but is not supported by browsers. If you want HTTP/2 in a browser context, you need HTTPS.

What is head-of-line blocking and does HTTP/2 fix it?

In HTTP/1.1, a slow response blocks all subsequent responses on the same TCP connection (head-of-line blocking). HTTP/2 fixes this at the HTTP layer with multiplexing — multiple streams share one connection without blocking each other. However, TCP-level head-of-line blocking still exists in HTTP/2. HTTP/3 (QUIC) eliminates it entirely.

Should I still use domain sharding or asset bundling with HTTP/2?

No. Domain sharding (splitting assets across multiple domains to open more TCP connections) and aggressive bundling were HTTP/1.1 workarounds for connection limits. With HTTP/2 multiplexing, they are counterproductive — sharding defeats connection reuse and bundling makes caching less granular. Serve assets from a single origin and let HTTP/2 multiplex them.

What is HPACK and why does it matter?

HPACK is the header compression algorithm used in HTTP/2. HTTP/1.1 sends headers as plain text on every request, including large cookies and User-Agent strings. HPACK maintains a shared compression table between client and server, so repeated headers (like Authorization or Cookie) are sent as short index references instead of full strings. This significantly reduces overhead for API-heavy applications.

Is HTTP/2 server push worth using?

Mostly no, in practice. Server push lets the server proactively send resources (e.g., CSS, JS) before the client requests them. However, it is difficult to implement correctly without over-pushing already-cached resources, and Chrome removed support for it in version 106 (2022). The 103 Early Hints status code is the modern replacement for the same use case.

References

Browse /search