ismile@portfolio:~$ cat notes/0013-http.md
HTTP
The biggest difference between HTTP/1.0 and HTTP/1.1 is how they manage connections and efficiency. HTTP/1.1 was designed to solve several limitations of HTTP/1.0.
HTTP/1.0 (1996)
1. One Request Per Connection
For every request, a new TCP connection is created and closed.
Client Server
| ---- GET /index ----> |
| <---- HTML ---------- |
Connection closed
| ---- GET /style.css ->|
| <---- CSS ----------- |
Connection closed
| ---- GET /logo.png -->|
| <---- Image --------- |
Connection closed
If a page contains 20 resources, the browser may need 20 separate TCP connections.
Problems
- High latency
- Repeated TCP handshakes
- Inefficient network usage
HTTP/1.1 (1997)
1. Persistent Connections (Keep-Alive)
A TCP connection stays open and can be reused for multiple requests.
Client Server
| ---- GET /index ----> |
| <---- HTML ---------- |
| ---- GET /style.css ->|
| <---- CSS ----------- |
| ---- GET /logo.png -->|
| <---- Image --------- |
Connection remains open
This eliminates the cost of creating a new TCP connection every time.
Other Improvements in HTTP/1.1
2. Host Header (Virtual Hosting)
HTTP/1.0:
GET /index.html
HTTP/1.1:
GET /index.html HTTP/1.1
Host: example.com
Because of the Host header, multiple websites can share the same IP address.
3. Chunked Transfer Encoding
HTTP/1.0 required the server to know the full content length beforehand:
Content-Length: 10000
HTTP/1.1 introduced:
Transfer-Encoding: chunked
The server can send data piece by piece:
Size
Data
4
Wiki
5
pedia
0
(end)
Useful for streaming or dynamically generated content.
4. Request Pipelining
HTTP/1.0:
Request 1 → Response 1
Request 2 → Response 2
Request 3 → Response 3
HTTP/1.1 allowed:
Request 1
Request 2
Request 3
---------------->
without waiting for previous responses.
However, responses must still come back in order:
<----------------
Response 1
Response 2
Response 3
Pipelining was rarely used because of the head-of-line blocking problem.
5. Additional Methods
HTTP/1.0 mainly used:
- GET
- POST
- HEAD
HTTP/1.1 standardized and expanded support for:
- GET
- POST
- HEAD
- PUT
- DELETE
- OPTIONS
- TRACE
- CONNECT
6. Better Caching
HTTP/1.1 added cache control headers:
Cache-Control: max-age=3600
ETag: "abc123"
If-None-Match: "abc123"
These help browsers and proxies avoid downloading unchanged resources.
Comparison Table
| Feature | HTTP/1.0 | HTTP/1.1 |
|---|---|---|
| Default connection | Close after each request | Persistent (Keep-Alive) |
| Multiple requests on one TCP connection | No | Yes |
| Host header | Optional | Required |
| Chunked transfer encoding | No | Yes |
| Request pipelining | No | Yes |
| Advanced caching | Limited | Improved |
| Additional methods | Few | More |
| Efficiency | Lower | Higher |
Example
HTTP/1.0
GET /index.html HTTP/1.0
(Server sends response)
Connection closed
HTTP/1.1
GET /index.html HTTP/1.1
Host: example.com
Connection: keep-alive
(Server sends response)
Connection stays open
HTTP/2 was introduced to solve some remaining performance problems in HTTP/1.1, especially head-of-line blocking caused by request ordering and the overhead of sending text headers repeatedly.
HTTP/1.1 Problem
Suppose a browser needs:
- HTML
- CSS
- JavaScript
- Images
With HTTP/1.1, even with Keep-Alive:
TCP Connection
──────────────────────────
Request 1 ──► HTML
Response 1 ◄── HTML
Request 2 ──► CSS
Response 2 ◄── CSS
Request 3 ──► JS
Response 3 ◄── JS
Request pipelining exists, but responses must arrive in order.
If one response is slow, everything behind it waits (Head-of-Line Blocking).
HTTP/2
HTTP/2 still uses TCP, but changes how data is transmitted.
Multiplexing
Multiple requests and responses can travel simultaneously over a single TCP connection.
Single TCP Connection
─────────────────────────────────
Request 1 (HTML) ─┐
Request 2 (CSS) ──┼────► Server
Request 3 (JS) ───┤
Request 4 (Image)─┘
◄──── HTML
◄──── Image
◄──── CSS
◄──── JS
Responses don't need to come back in request order.
Streams
Each request/response pair gets a stream ID.
Stream 1 → HTML
Stream 3 → CSS
Stream 5 → JS
Stream 7 → Image
The connection contains many streams simultaneously.
Frames
HTTP/2 breaks messages into small pieces called frames.
HTTP Response
↓
+--------+
| Frame 1|
+--------+
| Frame 2|
+--------+
| Frame 3|
+--------+
Frames from different streams are interleaved:
Frame(S1)
Frame(S3)
Frame(S1)
Frame(S5)
Frame(S7)
Frame(S3)
The receiver reconstructs them according to stream IDs.
Binary Protocol
HTTP/1.1:
GET /users HTTP/1.1
Host: example.com
Human-readable text.
HTTP/2:
110100101011...
Binary frames.
Advantages:
- Easier parsing
- Less ambiguity
- Faster processing
Header Compression (HPACK)
HTTP/1.1 repeatedly sends the same headers:
GET /css
Host: example.com
Cookie: session=abc
User-Agent: Chrome
Next request:
GET /js
Host: example.com
Cookie: session=abc
User-Agent: Chrome
Same headers are sent again.
HTTP/2 compresses and stores previous headers.
Instead of:
Host: example.com
Cookie: session=abc
User-Agent: Chrome
it can send:
Use header #5
This reduces bandwidth.
Server Push (Rarely Used Today)
Server can proactively send resources before the browser requests them.
Browser:
GET /
Server:
HTML
CSS
JS
without waiting for:
GET /style.css
GET /script.js
Server Push turned out to have limited benefit and is largely disabled in modern browsers.
Architecture
Application
HTTP/2
↓
Binary Frames
↓
Multiplexed Streams
↓
Single TCP Connection
↓
IP
Comparison
| Feature | HTTP/1.1 | HTTP/2 |
|---|---|---|
| Protocol format | Text | Binary |
| Connections | Multiple | Usually one |
| Keep-Alive | Yes | Yes |
| Multiplexing | No | Yes |
| Stream IDs | No | Yes |
| Header compression | No | HPACK |
| Server Push | No | Yes |
| Underlying transport | TCP | TCP |
Example
Suppose a webpage requires:
index.html
style.css
app.js
logo.png
HTTP/1.1
TCP Connection
GET index.html
← index.html
GET style.css
← style.css
GET app.js
← app.js
GET logo.png
← logo.png
HTTP/2
Single TCP Connection
Stream 1 → index.html
Stream 3 → style.css
Stream 5 → app.js
Stream 7 → logo.png
Frames are mixed together:
S1 S3 S5 S1 S7 S5 S3 ...
Responses return independently.
One Remaining Problem
HTTP/2 uses TCP, and TCP itself still suffers from connection-level Head-of-Line Blocking.
If one packet is lost:
Packet 1 ✓
Packet 2 ✓
Packet 3 ✗ lost
Packet 4 received
Packet 5 received
TCP delivers data in order, so packets 4 and 5 must wait until packet 3 is retransmitted.
Because all streams share one TCP connection, packet loss can temporarily stall every stream.
This limitation is one of the major reasons HTTP/3 moved from TCP to QUIC (UDP-based transport).