> For the complete documentation index, see [llms.txt](https://naz.gitbook.io/my-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://naz.gitbook.io/my-docs/basic-networking/http_1_vs_http_2_vs_http_3.md).

# HTTP 1 vs HTTP 2 vs HTTP 3

## What HTTP Is

HTTP (Hypertext Transfer Protocol) is how browsers talk to web servers — they ask for web pages and get them back. It was originally designed for hypertext documents containing links to other documents, but developers soon found it could carry images and video too. Today it also powers APIs, file transfers, and a wide range of web-based services.

***

## HTTP 0.9 — The Beginning

Before HTTP 1, there was HTTP 0.9. It was minimal:

* Only supported GET requests
* Had no headers
* Only sent HTML files
* No HTTP headers or status codes

The name "0.9" indicated it was a very early experimental version. It was designed solely for fetching hypertext documents — documents with links to other documents.

```mermaid
flowchart TB
    Browser[Browser] -->|GET /page.html| Server[Server]
    Server -->|HTML file| Browser

    style Browser fill:#fbbf24
    style Server fill:#f59e0b
    style HTML fill:#eab308
```

## HTTP 1.0 — Adding Structure

HTTP 1.0 added:

* Headers
* Status codes
* New methods: POST and HEAD

Each request worked straightforwardly — the browser asks for a page, the server sends it. But **every request required its own connection**, meaning a lot of back-and-forth overhead.

### Why HTTP 1.0 Was Inefficient

Before any data could be sent, two handshakes had to complete.

First, a three-way TCP handshake establishes the connection. The process uses specific flags to set up a reliable connection: SYN (Synchronize), SYN-ACK (Synchronize-Acknowledgment), and ACK (Acknowledgment).

Then, if the connection uses HTTPS, a TLS handshake negotiates security — the client sends a ClientHello, the server replies with its certificate, they exchange keys, and the server confirms. Only after both handshakes finish can the browser send its HTTP request and receive a response.

The critical problem: with HTTP 1.0, this entire sequence happened **for every single resource**. Every image, CSS file, and JavaScript file triggered its own TCP + TLS handshake from scratch.

```mermaid
sequenceDiagram
    participant Browser
    participant Server

    Note over Browser,Server: TCP Handshake (3-way)
    Browser->>Server: SYN
    Server->>Browser: SYN-ACK
    Browser->>Server: ACK

    Note over Browser,Server: TLS Handshake (for HTTPS)
    Browser->>Server: ClientHello
    Server->>Browser: ServerHello + Certificate
    Browser->>Server: Key Exchange
    Server->>Browser: Finished

    Note over Browser,Server: Now data can flow
    Browser->>Server: HTTP GET /index.html
    Server->>Browser: HTTP Response
```

With HTTP 1.0, this happened **for every resource** — every image, CSS file, and JavaScript file triggered its own TCP + TLS handshake.

***

## HTTP 1.1 — Persistent Connections (1997)

HTTP 1.1 fixed HTTP 1.0's inefficiencies and is still widely used today, even after 25+ years.

### Persistent Connections

Connections stay open unless explicitly closed with `Connection: close`. No more closing after every request, no more multiple TCP handshakes. This eliminated the overhead of constantly opening and closing connections.

### Pipelining

Clients could send multiple requests over one TCP connection without waiting for responses. Instead of requesting image1, waiting for it to arrive, then requesting image2, the browser sends both requests back-to-back as soon as it knows it needs them. The server processes them in order and sends the responses sequentially.

```mermaid
sequenceDiagram
    participant Browser
    participant Server

    Note over Browser,Server: Single TCP connection stays open
    Browser->>Server: GET /image1.png
    Browser->>Server: GET /image2.png
    Server->>Browser: Response: image1.png
    Server->>Browser: Response: image2.png
```

### Chunk Transfer Encoding

Servers could send responses in smaller chunks instead of waiting for the entire response to be ready. This made initial page rendering faster and improved user experience for large or dynamic content.

### Better Caching and Conditional Requests

Headers like `Cache-Control` and `ETag` helped manage cached content and reduce unnecessary data transfers. Conditional requests using headers like `If-Modified-Since` let clients fetch resources only if they had changed, saving bandwidth.

### The Head-of-Line Blocking Problem

Despite these improvements, HTTP 1.1 had a fundamental flaw:

**head-of-line blocking**. Even though pipelining lets you send multiple requests without waiting, the server **must send responses in the same order it received the requests.** If the first request is slow — say it takes 5 seconds to fetch a large resource — the second request, even if the server has it ready, must wait behind the slow one. The fast resource gets blocked by the slow resource ahead of it in line.

```mermaid
sequenceDiagram
    participant Browser
    participant Server

    Browser->>Server: GET /slow-resource (takes 5s)
    Browser->>Server: GET /fast-resource (must wait!)
    Note right of Server: Fast resource blocked behind slow one
    Server->>Browser: Response: slow-resource
    Server->>Browser: Response: fast-resource
```

Because of this, many browsers disabled pipelining entirely. Developers invented workarounds:

* **Domain sharding**: Serve static assets from subdomains; each new subdomain gave 6 more connections
* **File concatenation**: Bundle CSS/JS files together; combine images using sprites

***

## HTTP 2 — Multiplexing (2015)

HTTP 2 was designed to fix HTTP 1's performance problems. It brought major improvements.

### Binary Framing Layer

Unlike HTTP 1's plain text messages,

HTTP 2 uses binary format. Messages are divided into smaller units called **frames**, sent over the TCP connection. The binary framing layer handles all of this.

### Full Multiplexing

Clients and servers can break HTTP messages into independent frames that can be interleaved during transmission and reassembled on the other side. Unlike HTTP 1.1's pipelining,\
**HTTP 2 doesn't force responses to arrive in request order.** The browser sends two frames on different streams — one for image1 and one for image2. The server can respond to whichever finishes first, interleaving chunks from both responses. The browser reassembles each stream on arrival. This solved the head-of-line blocking problem from HTTP 1.1

```mermaid
sequenceDiagram
    participant Browser
    participant Server

    Note over Browser,Server: Single TCP connection
    Browser->>Server: Frame: stream1, GET /image1.png
    Browser->>Server: Frame: stream2, GET /image2.png
    Server->>Browser: Frame: stream2, image2 chunk
    Server->>Browser: Frame: stream1, image1 chunk
    Server->>Browser: Frame: stream2, image2 done
    Server->>Browser: Frame: stream1, image1 done
    Note right of Server: Frames interleaved — no blocking
```

### Stream Prioritization

The order of loading assets matters for web pages. Stream prioritization lets developers set the importance of requests — the browser tells the server which assets are high priority, and the server allocates more frames to those requests.

### Server Push

**HTTP 2 allows a server to send multiple responses to a single client request.** The server can send extra resources alongside the requested HTML page — giving the client resources before they even ask for them.

### Header Compression

In HTTP 1, only the body was compressed; headers were sent as plain text. HTTP 2 uses **HPACK** to compress headers. HPACK compresses headers and remembers past headers, using that knowledge to compress future headers even further.

***

## HTTP 3 — QUIC Instead of TCP (2022)

As web apps grew more complex and mobile internet became common, HTTP 2 revealed some limits. TCP's handling of packet loss and head-of-line blocking caused lower page loads, especially on high-latency or lossy networks.

### QUIC Replaces TCP

HTTP 3 uses **QUIC** instead of TCP. QUIC was developed by Google and is built on **UDP** — a connectionless protocol that doesn't need to set up a connection before sending data.

### Advantages of QUIC + HTTP 3

* Reduced latency
* Improved multiplexing without TCP head-of-line blocking
* Better handling of packet loss
* Better performance on mobile networks with seamless connection changes

### The QUIC Handshake

When a client connects to a server with HTTP 3, it starts a QUIC handshake. QUIC incorporates TLS 1.3 for security, and the TLS handshake happens during the QUIC connection setup — reducing overall latency. The client sends an initial packet containing the ClientHello and a key share. The server responds with its ServerHello, certificates, and a Finished message. The client confirms with its own Finished message, and the connection is ready. This combines what TCP and TLS did separately into a single handshake.

For return visits, QUIC supports 0-RTT: the client embeds a request with early data in the very first packet, and the server processes it without waiting for a full handshake. This is especially noticeable on repeat connections to the same server.

```mermaid
sequenceDiagram
    participant Client
    participant Server

    Note over Client,Server: QUIC Handshake (combined with TLS 1.3)
    Client->>Server: Initial (ClientHello + key share)
    Server->>Client: Handshake (ServerHello + certs + finished)
    Client->>Server: Finished
    Note over Client,Server: Connection ready — faster than TCP+TLS

    rect rgb(200, 255, 200)
    Note over Client,Server: Return visits: 0-RTT
    Client->>Server: Request + Early Data
    Server->>Client: Response
    Note right of Server: No full handshake needed
    end
```

HTTP 3 sets up connections faster than TCP. If the client and server have communicated before, QUIC can secure the connection in **one round trip** or sometimes **zero round trips** — the client sends a request immediately, and the server processes it without a full handshake.

### Handling Network Changes

If you switch from Wi-Fi to cellular on your phone, HTTP 3 keeps the connection going. This works because QUIC uses **connection IDs** that don't depend on IP addresses. When the phone's IP changes from the Wi-Fi address to the cellular address, the connection ID stays the same, so the server can continue the session without interruption.

```mermaid
flowchart LR
    Phone[Phone on Wi-Fi] -->|Switches to 4G| Phone2[Phone on Cellular]
    Phone2 --> Server[Server]
    Note[Connection ID persists across IP change]
```

***

## Adoption as of 2023

| Protocol | Status                                                              |
| -------- | ------------------------------------------------------------------- |
| HTTP 1.1 | Still widely used, especially for simple websites                   |
| HTTP 2   | Adopted heavily — handles over 60% of web requests                  |
| HTTP 3   | Still new but gaining traction; Google and Cloudflare lead adoption |

***

## Summary

```mermaid
flowchart TB
    HTTP09["HTTP 0.9<br/>GET only, no headers"] --> HTTP10["HTTP 1.0<br/>+ Headers, status codes, POST, HEAD"]
    HTTP10 --> HTTP11["HTTP 1.1<br/>+ Persistent connections, pipelining,<br/>chunk encoding, caching"]
    HTTP11 --> HTTP2["HTTP 2<br/>+ Binary framing, multiplexing,<br/>stream prioritization, server push,<br/>header compression"]
    HTTP2 --> HTTP3["HTTP 3<br/>+ QUIC over UDP, 0-RTT,<br/>no head-of-line blocking,<br/>seamless network switching"]
```

Each version evolved to solve the limitations of its predecessor — from eliminating per-request connection overhead, to enabling true multiplexing, to removing TCP as the bottleneck entirely. The web's foundational protocol has adapted to our growing need for fast, reliable online experiences.

***

## See also

* [Understanding HTTP for Backend Engineers](/my-docs/backend-learning/understanding_http_for_backend_engineers.md) — the backend perspective on HTTP
* [HTTP 1 vs HTTP 2 vs HTTP 3 (Blog)](https://github.com/nahomkasa999/Notes/tree/main/Blogs/blog-http-evolution.md) — the blog-style overview of the same evolution
