The Evolution of HTTP
HTTP is the foundational protocol of the Web. Starting with HTTP/0.9 in 1991, it has evolved to HTTP/3 today.
flowchart LR
H09["HTTP/0.9<br/>(1991)"] --> H10["HTTP/1.0<br/>(1996)"] --> H11["HTTP/1.1<br/>(1997)"]
H11 --> H2["HTTP/2<br/>(2015)"] --> H3["HTTP/3<br/>(2022)"]
HTTP/1.1 Challenges
Head-of-Line Blocking
With a single TCP connection, requests must be processed in order.
sequenceDiagram
participant Client
participant Server
Note over Client,Server: HTTP/1.1 - Sequential Processing
Client->>Server: Request 1
Server-->>Client: Response 1
Client->>Server: Request 2
Server-->>Client: Response 2
Client->>Server: Request 3
Note over Client,Server: If an earlier request blocks, subsequent ones must wait
Need for Multiple Connections
To ensure parallelism, browsers use 6-8 TCP connections per domain.
flowchart LR
subgraph Domain["example.com"]
C1["TCP 1: script.js"]
C2["TCP 2: style.css"]
C3["TCP 3: image1.jpg"]
C4["TCP 4: image2.jpg"]
C5["TCP 5: image3.jpg"]
C6["TCP 6: image4.jpg"]
end
→ Connection overhead, resource waste
HTTP/2 Features
Multiplexing
Multiple requests/responses can be processed in parallel over a single TCP connection.
flowchart TB
subgraph TCP["Single TCP Connection (HTTP/2)"]
subgraph Requests["Requests"]
R1["Req 1"]
R2["Req 2"]
R3["Req 3"]
R4["Req 4"]
end
subgraph Responses["Responses"]
S1["Res 1"]
S2["Res 2"]
S3["Res 3"]
S4["Res 4"]
end
R1 --> S1
R2 --> S2
R3 --> S3
R4 --> S4
end
→ Parallel processing, order-independent
Binary Protocol
Changed from HTTP/1.1’s text-based format to binary frames.
HTTP/1.1 (Text):
GET /index.html HTTP/1.1\r\n
Host: example.com\r\n
\r\n
HTTP/2 (Binary Frame):
| Field | Description |
|---|---|
| Length | Frame length |
| Type | Frame type |
| Flags | Frame flags |
| Stream ID | Stream identifier |
| Payload | Frame data |
Header Compression (HPACK)
Efficiently compresses headers and omits duplicate headers.
| Request | Headers |
|---|---|
| First request | :method: GET, :path: /index.html, :authority: example.com, user-agent: Mozilla/5.0..., accept: text/html |
| Second request | :path: /style.css (Others are same as before, so omitted) |
→ Header size significantly reduced
Server Push
The server can send resources before the client requests them.
sequenceDiagram
participant Client
participant Server
Client->>Server: Request index.html
Server->>Client: Response index.html
Server->>Client: Push style.css (sent without request)
Server->>Client: Push script.js
Note over Client,Server: Reduces RTT
Note: Server Push is rarely used in practice and has been disabled in Chrome 106 and later.
Priority Control
Set priorities on streams to process important resources first.
| Stream | Resource | Priority |
|---|---|---|
| Stream 1 | HTML | High |
| Stream 2 | CSS | High |
| Stream 3 | Image | Low |
→ Load HTML/CSS first
HTTP/2 Challenges
TCP-level Head-of-Line Blocking remains unsolved.
| Packet | Status | Result |
|---|---|---|
| Packet 1 | ✓ | OK |
| Packet 2 | ✓ | OK |
| Packet 3 | ✗ | Packet loss |
| Packet 4 | ✓ | Waiting at TCP layer |
| Packet 5 | ✓ | Waiting at TCP layer |
→ One packet loss blocks all streams
HTTP/3 and QUIC
HTTP/3 uses the QUIC protocol (built on UDP) instead of TCP.
QUIC Features
flowchart TB
subgraph Traditional["Traditional"]
A1["Application Layer: HTTP/2"]
T1["Transport Layer: TCP + TLS"]
N1["Network Layer: IP"]
A1 --> T1 --> N1
end
subgraph HTTP3["HTTP/3"]
A2["Application Layer: HTTP/3"]
T2["Transport Layer: QUIC<br/>(UDP + TLS 1.3 integrated)"]
N2["Network Layer: IP"]
A2 --> T2 --> N2
end
Stream Independence
Each stream is independent, so one packet loss doesn’t affect other streams.
| Stream | Packet Status | Result |
|---|---|---|
| Stream 1 | Packet 1 ✓ | Continue processing |
| Stream 2 | Packet 2 ✗ (loss) | Only this stream waits for retransmission |
| Stream 3 | Packet 3 ✓ | Continue processing |
→ Streams are independent
0-RTT Connection
Reconnection to previously connected servers is faster.
Traditional TCP + TLS:
| Step | Action |
|---|---|
| 1 | TCP SYN |
| 2 | TCP SYN-ACK |
| 3 | TCP ACK + TLS ClientHello |
| 4 | TLS ServerHello |
| 5 | TLS Finished |
| 6 | Start data transmission |
QUIC 0-RTT:
| Step | Action |
|---|---|
| 1 | QUIC Initial (previous session info + data) |
→ Can send data from the first packet
Connection Migration
Connections can be maintained even when IP address changes.
| Protocol | WiFi → Mobile network |
|---|---|
| Traditional | IP address change = Connection dropped = Reconnect |
| QUIC | Connection ID maintained = Seamless continuation |
Performance Comparison
| Aspect | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|
| Connections | Multiple required | 1 connection | 1 connection |
| HoL Blocking | Yes | Partially solved | Solved |
| Connection establishment | Slow | Slow | Fast |
| Packet loss resilience | Low | Low | High |
| Mobile support | Weak | Normal | Strong |
Checking Support Status
// Check in browser
if (window.performance) {
const entries = performance.getEntriesByType('navigation');
console.log(entries[0].nextHopProtocol);
// → "h2" (HTTP/2) or "h3" (HTTP/3)
}
# Check with curl
curl -I --http2 https://example.com
curl -I --http3 https://example.com
Server Configuration Examples
Nginx (HTTP/2)
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
}
Cloudflare (HTTP/3)
If using Cloudflare, you can enable HTTP/3 from the dashboard.
Summary
HTTP/2 significantly improved upon HTTP/1.1 challenges through multiplexing and header compression. HTTP/3 further enhances packet loss resilience and mobile support through the QUIC protocol. Modern websites are recommended to support HTTP/2 or higher.
← Back to list