HTTP/2

HTTP/2 is a major revision of the HyperText Transfer Protocol, published in May 2015 as RFC 7540 and revised in June 2022 as RFC 9113. The protocol replaces the text-based messaging of HTTP/1.1 with a binary framing layer enabling multiplexed streams, header compression, and more efficient use of TCP connections.

HTTP/2 preserves full backward compatibility with HTTP/1.1. All HTTP methods, status codes, and header fields remain the same. The changes are in how data is framed and transported, not in what the data means.

Baseline: Widely available

Supported in all major browsers. webstatus.dev

SPDY origins

Google announced the SPDY ("speedy") protocol in 2009 as an experiment to reduce web page load latency. SPDY introduced binary framing, multiplexing, header compression, and server push over a single TLS connection.

After SPDY demonstrated measurable improvements and gained adoption in Firefox and Opera, the IETF selected SPDY as the starting point for HTTP/2. The initial HTTP/2 draft was based directly on SPDY. SPDY was deprecated after HTTP/2 was ratified, and browser support was removed in 2016.

Binary framing

HTTP/2 encodes all communication as binary frames. Each frame has a 9-byte header containing the length, type, flags, and a 31-bit stream identifier. Frames are the smallest unit of communication.

Three concepts define the transport model:

  • Frame: a single unit of data identified by stream ID and type
  • Message: a complete sequence of frames mapping to an HTTP request or response
  • Stream: an independent, bidirectional sequence of frames within a connection

All streams share a single TCP connection. Frames from different streams are interleaved and reassembled at the receiving end based on stream identifiers.

Frame types

Frame Type Purpose
DATA 0x00 Carries request or response body
HEADERS 0x01 Opens a stream; carries header fields
PRIORITY 0x02 Stream priority (deprecated)
RST_STREAM 0x03 Terminates a single stream
SETTINGS 0x04 Connection configuration
PUSH_PROMISE 0x05 Server push notification
PING 0x06 Round-trip time measurement
GOAWAY 0x07 Graceful connection shutdown
WINDOW_UPDATE 0x08 Flow control adjustment
CONTINUATION 0x09 Continues a HEADERS block

RST_STREAM allows a client to cancel a specific stream (for example, when navigating away from a page) without affecting other streams or closing the connection.

Multiplexing

Multiplexing allows multiple HTTP requests and responses to be in flight simultaneously on a single TCP connection. This addresses the head-of-line blocking problem from HTTP/1.1, where responses had to arrive in order on each connection.

With HTTP/1.1, browsers used up to six parallel TCP connections per origin to achieve concurrency. With HTTP/2, a single connection handles all requests concurrently through interleaved streams. This reduces TCP handshake overhead, improves congestion window utilization, and lowers server resource consumption.

TCP-level blocking remains

HTTP/2 solves HTTP-level head-of-line blocking. TCP-level head-of-line blocking remains: a single lost TCP packet stalls all streams until retransmission completes. At high packet loss rates, HTTP/1.1 with multiple connections isolates losses better. This limitation motivated HTTP/3, which runs on QUIC over UDP.

HPACK header compression

HTTP/2 compresses Headers using HPACK (RFC 7541). HPACK uses three mechanisms:

  • Static table: 61 predefined entries for commonly used header name-value pairs (:method: GET, :scheme: https, accept-encoding: gzip, deflate)
  • Dynamic table: a FIFO table storing recently encoded headers, shared between encoder and decoder
  • Huffman encoding: variable-length binary codes compress string literals (5–30 bits per character)

HPACK was designed to resist the CRIME attack, which exploited character-by-character guessing in DEFLATE compression. HPACK only reveals matches on complete header values and supports never-indexed literals for sensitive fields like Cookies and authorization tokens.

Pseudo-header fields

HTTP/2 replaces the HTTP/1.1 request line and status line with pseudo-header fields, prefixed with : (colon). These are not regular HTTP headers and must appear before all regular header fields.

Field Purpose
:method HTTP method
:scheme flow-control-

http/2-implements-credit-based-flow-control-at-both-the-stream-and-connection-level-using-window_update-frames.-each-new-stream-starts-with-a-65,535-byte-window.-only-data-frames-are-subject-to-flow-control.-control-frames-are-always-delivered.

-stream-prioritization-

rfc-7540-defined-a-priority-system-using-dependency-trees-and-stream-weights.-in-practice,-implementations-varied-widely,-and-many-servers-ignored-client-priority-signals-entirely.

-

rfc-9113-deprecated-the-original-scheme.-rfc-9218-(extensible-prioritization-scheme-for-http)-introduced-a-simpler-priority-header-field-working-across-both-http/2-and-[[3">HTTP/3.

Server push

Server push allowed a server to proactively send responses before the client requested them, using PUSH_PROMISE frames. The intent was to eliminate round trips for resources the server anticipated the client needed.

Deprecated in browsers

Chromium-based browsers removed server push support. Usage was low (under 1% of sites) and the mechanism caused more problems than server push solved. Servers had no way to know what the client already had cached, and pushed resources competed for bandwidth with explicitly requested content. The 103 Early Hints status code and <link rel="preload"> are the recommended alternatives.

ALPN negotiation

HTTP/2 is negotiated during the TLS handshake via the Application-Layer Protocol Negotiation (ALPN) extension. The client lists supported protocols in the ClientHello. The server selects one in the ServerHello.

  • h2: HTTP/2 over TLS
  • h2c: HTTP/2 over cleartext TCP (deprecated in RFC 9113, rarely used)

All major browsers only support HTTP/2 over TLS.

The connection begins with a 24-byte client preface (PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n) followed by a SETTINGS frame. This sequence was designed to cause HTTP/1.1 servers to reject the connection cleanly.

Network layers

HTTP/1.1 operates as two or three layers depending on whether TLS is present: HTTP over TCP, or HTTP over TLS over TCP. HTTP/2 clarified this by effectively requiring TLS, creating a consistent three-layer stack: HTTP/2 over TLS over TCP. All three layers remain independent. The binary framing sits above TLS, which sits above TCP.

HTTP/3 breaks from this model by integrating TLS directly into the QUIC transport, collapsing the three layers into two. This tighter integration is what enables the connection setup improvements and encryption of transport-level headers.

Security

HTTP/2 effectively requires TLS in practice. RFC 9113 Section 9.2 mandates TLS 1.2 at minimum, prohibits TLS compression (CRIME mitigation), prohibits TLS renegotiation, and requires ephemeral key exchange. A list of prohibited cipher suites includes many common TLS 1.2 defaults.

HTTP/2 Rapid Reset (CVE-2023-44487)

This vulnerability exploits multiplexing and RST_STREAM: an attacker rapidly opens and immediately cancels streams, causing significant server-side overhead with minimal client cost. The attack produced record-breaking DDoS volumes. Mitigations include rate-limiting stream creation and reset frequency.

Adoption

HTTP/2 adoption was rapid because existing websites and server applications required no changes. The protocol is transparent to application code. All major browsers support HTTP/2 over TLS.

Despite technical allowance for cleartext HTTP/2, browser vendors collectively chose to support HTTP/2 only over HTTPS. This decision raised the security floor for the entire web. Deploying HTTP/2 meant deploying TLS.

Optimization

HTTP/1.1 performance workarounds like domain sharding, CSS sprites, and script bundling become counterproductive with HTTP/2. Domain sharding prevents the single-connection advantage. Bundling defeats granular Caching. Small, individual requests are easier for the browser to cache and prioritize.

Testing HTTP/2

Browser DevTools

Open the Network tab, right-click the column headers, and enable Protocol. HTTP/2 connections show as h2.

curl

curl --http2 -I https://example.re

The response status line shows HTTP/2 when the server supports HTTP/2. Use -v (verbose) to see ALPN negotiation during the TLS handshake.

Online tools

  • http2.org: tests HTTP/2 support and reports ALPN negotiation details

nghttp

The nghttp command-line client (part of nghttp2) provides detailed HTTP/2 frame-level output:

nghttp -nv https://example.re

This shows the full frame exchange including SETTINGS, HEADERS, and DATA frames, useful for debugging HTTP/2 behavior at the protocol level.

Takeaway

HTTP/2 modernized HTTP transport through binary framing, multiplexed streams, and HPACK header Compression. The protocol delivers significant performance improvements over HTTP/1.1 on most networks while maintaining full semantic compatibility. The remaining TCP-level head-of-line blocking limitation is addressed by HTTP/3.

See also

Last updated: March 9, 2026