HTTP/2: Architecture, Features, and Practical Use
Learn how HTTP/2 uses binary framing, multiplexed streams, HPACK, flow control, ALPN, and persistent connections, with deployment and troubleshooting examples.
HTTP/2 is a major revision of the Hypertext Transfer Protocol. It preserves the familiar web model—clients send requests and servers return responses—but changes how those messages are represented and transported. Instead of sending mostly textual messages in a sequence, HTTP/2 uses binary frames and multiplexes many streams over one connection.
This lesson assumes familiarity with HTTP methods, status codes, headers, URLs, HTTPS, TCP, and basic web-server configuration. For background, see HTTP fundamentals, computer networking, and TCP and UDP ports.
HTTP/2 overview and purpose
HTTP/2 keeps application semantics compatible with HTTP/1.1. A browser can still request a URI with methods such as GET and POST, receive status codes such as 200 or 404, inspect headers, and process content types such as text/html or image/png. The important change is the protocol layer that frames and schedules those messages.
HTTP/1.1 commonly suffers from inefficient connection use and request queuing. Browsers opened multiple connections or used techniques such as domain sharding, concatenated assets, and image sprites to increase parallelism. HTTP/2 was designed to reduce latency and connection overhead while allowing many requests and responses to progress concurrently.
HTTP/2 grew from ideas demonstrated by Google's SPDY protocol. Its standards history includes RFC 7540, later replaced by RFC 9113. Implementations should follow the current standards and security guidance rather than relying on old assumptions.
The HTTP request-response model
A client requests a resource by sending a method, target URI, headers, and sometimes a request body. The server returns a status code, response headers, and sometimes a response body. For example, a browser might request an HTML document, then request its stylesheet, scripts, fonts, and images.
HTTP/2 does not replace these concepts. It changes the wire representation: a logical request or response is divided into one or more binary frames, associated with a stream. Content negotiation, cookies, caching headers, authentication, redirects, and content types continue to operate at the HTTP application level.
Binary framing layer
HTTP/1.1 messages are primarily textual. HTTP/2 divides communication into typed binary frames, the smallest protocol units. Each frame has a header containing a payload length, frame type, flags, and a stream identifier. The payload carries data or control information appropriate to that type.
- Length: identifies the frame payload size.
- Type: identifies DATA, HEADERS, SETTINGS, or another frame kind.
- Flags: provide type-specific signals, such as end of headers or end of stream.
- Stream identifier: associates stream-specific frames with a logical exchange; connection-wide frames use stream identifier zero.
Binary framing gives parsers explicit boundaries instead of requiring them to interpret delimiters and textual syntax. It also allows frames belonging to different streams to be interleaved safely.
Streams, messages, and multiplexing
A stream is an independent bidirectional sequence of frames within one HTTP/2 connection. An HTTP message is the logical request or response carried by that stream. A single connection can therefore carry the HTML response, a stylesheet response, and several image responses at the same time.
Multiplexing means interleaving frames from multiple streams over one connection. The sender might transmit header frames for stream 1, data for stream 3, then more data for stream 1. This removes the HTTP/1.1 application-layer problem in which one queued response can delay unrelated responses.
Client-initiated streams normally use odd-numbered identifiers, while server-initiated streams use even-numbered identifiers. Stream states include idle, open, half-closed, reserved, and closed. A stream may become half-closed when one side has finished sending but can still receive data. A stream-specific failure can be terminated with RST_STREAM without destroying other streams.
Connection management
An HTTP/2 connection usually consists of one TCP connection, commonly protected by TLS, carrying many streams. Persistent connections can be reused for multiple resources, reducing repeated handshakes and connection setup.
Startup includes protocol identification, a connection preface, and an exchange of SETTINGS frames. Settings communicate parameters such as the maximum concurrent streams, initial flow-control window, maximum frame size, and header-table capacity. Each endpoint acknowledges received settings.
GOAWAY provides graceful shutdown. It tells the peer that the connection is closing and identifies the highest stream that was processed. New work can move to another connection while eligible existing streams finish. A connection error affects the entire connection; a stream error affects only one stream.
Core HTTP/2 frame types
| Frame type | Purpose | Scope | Typical use |
|---|---|---|---|
| DATA | Carries message-body bytes | Stream | HTML, JSON, uploads, and downloads |
| HEADERS | Carries a header block | Stream | Request or response headers |
| CONTINUATION | Continues a header block | Stream | Header blocks too large for one frame |
| SETTINGS | Communicates connection parameters | Connection | Limits and feature settings |
| WINDOW_UPDATE | Increases a flow-control window | Stream or connection | Permitting more DATA |
| PING | Tests liveness or measures a round trip | Connection | Health and latency checks |
| RST_STREAM | Terminates one stream | Stream | Canceling a request |
| GOAWAY | Begins connection shutdown | Connection | Maintenance or fatal connection errors |
| PRIORITY | Communicates priority information | Stream | Scheduling hints in the original model |
| PUSH_PROMISE | Announces a promised server stream | Connection and stream context | Server push |
Unknown frame types can generally be ignored by endpoints that do not understand them, allowing protocol extensions. Implementations must still validate frame lengths, flags, stream identifiers, and ordering rules.
HPACK header compression
Headers can be expensive because requests repeatedly send values such as cookies, user agents, cache directives, and authorization metadata. HTTP/2 uses HPACK to reduce this repetition.
- The static table contains common header names and values known to both endpoints.
- A dynamic table stores recently observed header fields for later reuse.
- Indexed representations refer to table entries instead of repeating full values.
- Header blocks are carried by HEADERS frames and, when necessary, CONTINUATION frames.
HPACK was designed with compression security in mind. Generic compression of attacker-influenced and secret data can enable cross-request information leaks. HPACK's table model and encoding rules avoid treating the entire connection as one ordinary compression stream, although applications must still protect secrets and configure limits carefully.
Header list size limits protect memory and CPU. Rejecting oversized headers can appear as request failures, so limits should be coordinated across browsers, CDNs, proxies, and origins.
Flow control
Flow control prevents a fast sender from overwhelming a slow receiver. HTTP/2 has both a connection-level window and an individual window for each stream. DATA consumes available window space. A receiver sends WINDOW_UPDATE when it is ready to accept more data.
This matters when a large download shares a connection with critical page resources, or when a client uploads several large request bodies. Poor window management can make transfers stall even when the network has capacity. Flow control is different from congestion control: flow control protects the receiver, while TCP congestion control responds to network capacity and packet loss.
Prioritization
Resource priority can affect rendering. A browser may prefer the HTML document and critical CSS before below-the-fold images. The original HTTP/2 model represented relationships with dependencies, weights, and priority trees. PRIORITY frames and priority information associated with HEADERS could communicate these scheduling hints.
Support has varied between browsers, servers, proxies, and CDNs. Priority trees were not applied consistently, and a priority setting cannot compensate for slow application work or a congested network. Modern HTTP specifications use more extensible prioritization concepts, but operators should measure results rather than assume that a particular priority always improves performance.
Server push
Server push allowed a server to proactively send a resource likely to be requested. A server used PUSH_PROMISE to announce a promised stream and could then send its response before the client made a separate request. Clients could disable or reject pushes.
Push interacts with the cache: sending a resource already cached wastes bandwidth, and guessing incorrectly sends data that may never be used. Browser support and practical benefits declined because preload hints and accurate client-driven requests are often easier to control. Treat server push as a legacy or specialized capability, not a default optimization.
HTTP/2 over TLS and cleartext
HTTP/2 over TLS is commonly identified by the ALPN token h2. Cleartext HTTP/2 is called h2c. Public browsers generally require HTTPS for HTTP/2, so browser-facing deployments need a valid certificate, suitable TLS versions and cipher suites, and ALPN support.
During a TLS handshake, ALPN—Application-Layer Protocol Negotiation—lets the client and server select a protocol such as h2 or http/1.1. ALPN selection is separate from certificate validation: a successful certificate check proves the endpoint's identity and secure TLS setup, while ALPN determines the application protocol.
Where supported, h2c can use an HTTP Upgrade request. A non-TLS client can also use prior knowledge, directly starting HTTP/2 when both endpoints already know that protocol is expected. This is useful for controlled internal or server-to-server testing, not ordinary public browser traffic.
Protocol negotiation and fallback
If TLS negotiation selects h2, the client starts HTTP/2. If HTTP/2 is unavailable, compatible clients normally fall back to HTTP/1.1. A website can therefore serve different clients with different protocol versions.
Verify the result in browser developer tools by displaying the Network panel's protocol column. A request reported as h2 used HTTP/2 on that observed hop; http/1.1 indicates fallback. A CDN may use HTTP/2 between the browser and edge while using HTTP/1.1 between edge and origin.
HTTP/2 performance characteristics
HTTP/2 reduces repeated connection overhead and handles independent resources concurrently. Pages with many small CSS, JavaScript, font, and image resources often benefit. It also reduces the need for domain sharding and extreme asset concatenation, which can create extra connections or make caching less effective.
HTTP/2 does not automatically make every site faster. TCP packet loss can delay every multiplexed stream on the affected connection. Slow database queries, large media, poor caching, inefficient JavaScript, server scheduling, intermediary buffering, and weak network conditions can dominate the result.
| Characteristic | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|
| Message framing | Text-oriented messages | Binary frames | Binary frames over QUIC |
| Transport | TCP, optionally TLS | TCP, commonly TLS | QUIC over UDP, secured by TLS |
| Multiplexing behavior | Usually multiple connections and request queues | Many streams on one TCP connection | Many independently progressing QUIC streams |
| Header compression | Usually no shared indexed header compression | HPACK | QPACK |
| Head-of-line blocking | Application-level queuing and connection effects | No HTTP-level blocking between streams, but TCP loss can block the connection | Mitigates TCP transport-level blocking between streams |
| Typical negotiation | ALPN http/1.1 or Upgrade in applicable cases | ALPN h2 or h2c mechanisms | ALPN such as h3 |
| Browser deployment | Fallback remains widely necessary | Common for HTTPS sites | Can coexist with HTTP/2 |
Migrating an application from HTTP/1.1
- Confirm that certificates, TLS versions, cipher suites, and ALPN are correctly configured.
- Enable HTTP/2 at the client-facing CDN, load balancer, reverse proxy, or origin.
- Retain HTTP/1.1 fallback for older clients and incompatible network paths.
- Reassess domain sharding, aggressive JavaScript or CSS bundling, and image sprites. Keep improvements that remain useful, such as image compression, caching, and sensible code splitting.
- Test pages containing many concurrent resources, large uploads, and large downloads.
- Monitor negotiated protocol, stream resets, connection errors, latency, cache performance, and delivery failures.
Deployment layers and operations
| Layer | Possible HTTP/2 role | Verification method | Common concern |
|---|---|---|---|
| Browser client | Negotiates h2 and opens streams | Developer tools | Browser policy, cache, or fallback |
| CDN | Terminates client HTTP/2 | CDN diagnostics and response traces | Different protocol to origin |
| Load balancer | Terminates or forwards HTTP/2 | Listener and access-log settings | ALPN, timeout, and stream limits |
| Reverse proxy | Handles streams and forwards requests | Verbose logs and frame-aware tools | Buffering or protocol translation |
| Application server | Processes HTTP/2 requests | Server metrics and logs | Library or worker limitations |
| Origin service | Receives HTTP/2 directly or through a proxy | Direct controlled tests | Certificate and network-path differences |
Set safe limits for concurrent streams, header-list size, frame size, request bodies, idle connections, and timeouts. These limits help prevent resource exhaustion and malformed-frame attacks. Log the protocol version, negotiated ALPN value where available, connection identifiers, stream errors, GOAWAY events, and response timing without exposing sensitive headers.
HTTP/2 configuration examples
Nginx
server {
listen 443 ssl;
http2 on;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
Directive syntax varies by Nginx version; some releases use a listen directive containing the HTTP/2 parameter. Validate the configuration and reload it only after confirming the certificate and private-key paths.
Apache HTTP Server
<VirtualHost *:443>
ServerName example.com
Protocols h2 http/1.1
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.com.pem
SSLCertificateKeyFile /etc/ssl/private/example.com.key
</VirtualHost>
The server needs suitable TLS and HTTP/2 modules. Keeping http/1.1 in the protocol list preserves fallback compatibility.
Testing and debugging HTTP/2
Using curl
curl -I -v --http2 https://example.com/
curl -I -v --http1.1 https://example.com/
In verbose output, look for ALPN selecting h2 and an HTTP/2 response. The installed curl must have HTTP/2 support. Comparing with forced HTTP/1.1 helps identify fallback behavior and connection differences.
Inspecting ALPN with OpenSSL
openssl s_client -connect example.com:443 -servername example.com -alpn h2
Review the negotiated ALPN protocol. This checks TLS negotiation, not the complete HTTP request and response exchange.
Viewing frames with nghttp
nghttp -nv https://example.com/
An HTTP/2-aware client can expose SETTINGS, HEADERS, DATA, stream identifiers, window updates, resets, and shutdown events. Browser developer tools are useful for waterfalls and rendering metrics; frame traces are better for protocol-level diagnosis.
Common troubleshooting cases
The browser uses HTTP/1.1
- Check the browser Network panel's protocol column.
- Run
curl -I -v --http2 https://example.com/. - Inspect ALPN with OpenSSL.
- Check HTTP/2 and ALPN at the CDN, load balancer, reverse proxy, and origin separately.
- Confirm that the browser-facing request uses HTTPS and that incompatible TLS libraries or proxies have been updated.
HTTP/2 works at the CDN but not at the origin
The CDN may terminate HTTP/2 at the edge and use HTTP/1.1 to the origin. Identify every hop and inspect the CDN's origin protocol setting. End-to-end HTTP/2 is a separate deployment decision and is not required merely because edge traffic uses h2.
Performance did not improve
Measure server processing time, transfer sizes, cache hit rates, rendering metrics, and packet loss. Compare resource waterfalls under representative latency. Optimize application processing, media, caching, compression, and delivery scheduling independently of the protocol version.
Streams reset or connections close
Inspect RST_STREAM, GOAWAY, and error-code events with timestamps across client, proxy, and server logs. Look for mismatched limits, timeouts, resource exhaustion, and outdated implementations. Align settings and timeouts, apply patches, and scale or rate-limit overloaded services.
Large transfers stall
Inspect frame traces for WINDOW_UPDATE. An exhausted stream or connection window, slow receiver, intermediary buffering, TCP retransmissions, or congestion can stop progress. Correct flow-control and buffering settings within safe limits and investigate network capacity.
Security considerations
- Use valid certificates and a maintained TLS configuration for normal browser-facing HTTP/2.
- Keep HTTP/2 libraries, proxies, CDNs, and servers patched.
- Limit header-list sizes and dynamic table resources to control expensive decoding.
- Limit concurrent streams, request rates, frame rates, request-body sizes, and idle connection duration.
- Monitor rapid stream resets, excessive concurrent streams, malformed frames, and unusual connection creation.
- Remember that HPACK reduces header repetition but does not make secrets safe to expose in headers.
Feature benefits and caveats
| Feature | Benefit | Caveat or limitation | Operational guidance |
|---|---|---|---|
| Multiplexing | Concurrent resource delivery over fewer connections | TCP loss can affect all streams on a connection | Measure under real network conditions |
| HPACK | Reduces repetitive header bytes | Tables and header decoding consume resources | Set coordinated header limits |
| Flow control | Protects receivers from overload | Small or mishandled windows can stall transfers | Trace WINDOW_UPDATE behavior |
| Prioritization | Can favor render-critical resources | Support and scheduling vary | Verify with waterfalls and metrics |
| Server push | Can send a predicted resource early | May waste bandwidth and has declining browser support | Use only for specialized, measured cases |
| TLS with ALPN | Securely negotiates h2 for browsers | Certificate or intermediary errors cause fallback | Test each TLS termination point |
HTTP/2, HTTP/1.1, and HTTP/3
HTTP/1.1 uses textual framing and commonly relies on multiple connections or queued requests for parallel loading. HTTP/2 uses binary framing and multiplexed streams over TCP, removing HTTP-level response queuing between streams. HTTP/3 uses QUIC, a UDP-based transport with independently progressing streams, reducing the transport-level head-of-line effects caused by TCP packet loss.
HTTP/1.1 remains necessary for older clients, unsupported intermediaries, and some controlled environments. HTTP/2 and HTTP/3 can coexist on the same site: clients negotiate the version they support, while a CDN or server may use different protocols on different network hops.
Exam-relevant notes
- HTTP/2 changes framing and transport behavior while preserving HTTP application semantics.
- Frames belong to streams, and many streams can be multiplexed on one connection.
- HPACK compresses headers with static and dynamic tables.
- Flow control has both stream-level and connection-level windows.
SETTINGScommunicates parameters;WINDOW_UPDATEgrants more flow-control capacity;RST_STREAMcancels one stream;GOAWAYshuts down a connection gracefully.h2identifies HTTP/2 over TLS, whileh2cidentifies cleartext HTTP/2.- ALPN selects the application protocol during TLS; it does not validate the certificate.
- HTTP/2 removes HTTP/1.1 application-layer head-of-line blocking but remains affected by TCP-level packet loss.
- Server push is specialized and should not be assumed to improve performance.