HTTP/2 (RFC 9113) and HTTP/3 (RFC 9114) are the modern versions of the Hypertext Transfer Protocol. HTTP/2 brought binary framing, multiplexing, and header compression to address the limitations of HTTP/1.1. HTTP/3 replaces TCP with QUIC (a UDP-based transport) to eliminate TCP-level head-of-line Blocking and enable features like connection migration.
Both protocols maintain the same HTTP semantics (methods, status codes, headers, URIs) as HTTP/1.1. The change is in how the bytes are formatted on the wire, not in what they mean.
HTTP/1.1 is a text protocol. HTTP/2 is a binary protocol. Every HTTP/2 communication is performed Over a single TCP connection, and all communication is split into smaller messages and frames.
A stream is a bidirectional flow of frames within a single HTTP/2 connection. Multiple streams are Multiplexed over a single TCP connection. Each stream has a unique 31-bit identifier. Client-initiated streams use odd numbers; server-initiated streams use even numbers.
Client Server
| |
|--- HEADERS [stream 1] ----------------------->| GET /style.css
|--- HEADERS [stream 3] ----------------------->| GET /script.js
|--- HEADERS [stream 5] ----------------------->| GET /image.png
| |
|<-- HEADERS [stream 1] ------------------------| 200 OK
|<-- DATA [stream 1] ---------------------------| CSS content
|<-- HEADERS [stream 3] ------------------------| 200 OK
|<-- DATA [stream 3] ---------------------------| JS content
|<-- HEADERS [stream 5] ------------------------| 200 OK
|<-- DATA [stream 5] ---------------------------| Image data
No ordering requirement exists between streams. The server can send stream 5”s data before stream 1’s, and the client reassembles each stream independently.
HTTP/2 implements flow control at the stream level and the connection level. Each side advertises a Window size (initially 65,535 bytes, configurable via SETTINGS). The sender must not send more data Than the receiver’s window allows. The receiver sends WINDOW_UPDATE frames to increase the window.
This prevents a fast sender from overwhelming a slow receiver. Without flow control, a server Sending a large response could exhaust the client’s receive buffer.
Client Server
| |
|<-- DATA [stream 1, 16KB] --------------------| (client window decreases)
|<-- DATA [stream 1, 16KB] --------------------| (client window decreases)
|--- WINDOW_UPDATE [stream 1, +32KB] ---------->| (client grants more window)
|<-- DATA [stream 1, 32KB] --------------------| (server can send more)
HTTP/1.1 sends headers as plain text, repeated on every request. For a typical page load with 30-100 Requests, headers like User-Agent``Accept``CookieAnd Accept-Encoding are sent dozens of Times, each time consuming hundreds of bytes.
HPACK (RFC 7541) compresses headers using three techniques:
HTTP/2 is like upgrading from a single-lane road to a multi-lane highway. HTTP/1.1 forces all requests to wait in line (head-of-line blocking), while HTTP/2 lets multiple requests travel simultaneously in separate lanes (streams) on the same connection. Header compression is like using abbreviations for frequently used phrases - instead of repeating the full address every time, you use a short code. HTTP/3 goes further by replacing the road entirely - QUIC runs over UDP, eliminating TCP’s requirement that all packets arrive in order. This is like switching from a convoy system (where a slow truck blocks everyone) to independent delivery drones that can take different paths. The key insight is that these versions improve transport mechanics without changing HTTP semantics.