HTTP/1.1 — The Foundation
HTTP/1.1 (RFC 2616, later refined by RFC 7230-7235) is a text-based, request-response protocol. The client sends a plaintext request with a method, path, headers, and optional body. The server responds with a status code, headers, and a body.
Methods
Retrieve a resource. Safe, idempotent, cacheable. No request body by convention.
Submit data to create a resource or trigger processing. Not idempotent.
Replace the entire resource at the target URI. Idempotent.
Partial update of a resource. Not necessarily idempotent.
Remove the resource. Idempotent.
HEAD returns headers only. OPTIONS returns allowed methods (used in CORS preflight).
Key Headers
Host (required in HTTP/1.1), Content-Type, Content-Length, Authorization, Cache-Control, Accept-Encoding, Connection: keep-alive, Transfer-Encoding: chunked.
Status Codes
| Code | Meaning | Notes |
|---|---|---|
200 | OK | Standard success response |
201 | Created | Resource created (POST/PUT) |
204 | No Content | Success with no body (DELETE) |
301 | Moved Permanently | Permanent redirect, method may change to GET |
302 | Found | Temporary redirect, method may change |
304 | Not Modified | Cached version is still valid |
400 | Bad Request | Malformed request syntax |
401 | Unauthorized | Missing or invalid authentication |
403 | Forbidden | Authenticated but not authorized |
404 | Not Found | Resource does not exist |
429 | Too Many Requests | Rate limiting; check Retry-After |
500 | Internal Server Error | Unhandled server-side failure |
502 | Bad Gateway | Upstream server returned invalid response |
503 | Service Unavailable | Server overloaded or in maintenance |
504 | Gateway Timeout | Upstream server did not respond in time |
Keep-Alive & Chunked Transfer
HTTP/1.0 opened a new TCP connection for every request. HTTP/1.1 defaults to persistent connections via Connection: keep-alive, reusing the same TCP connection for multiple requests. Transfer-Encoding: chunked allows the server to stream a response in pieces without knowing the total Content-Length upfront.
HTTP/2 — Binary & Multiplexed
HTTP/2 (RFC 7540, 2015) keeps the same semantics (methods, status codes, headers) but fundamentally changes how data is framed and transported over the wire.
Binary Framing Layer
Instead of plaintext, HTTP/2 uses a binary framing layer. Each HTTP message is broken into small binary frames (HEADERS frame, DATA frame, etc.) that are interleaved on a single TCP connection.
Multiplexing
Multiple requests and responses are sent concurrently as interleaved frames over a single TCP connection. Each request-response pair lives on its own numbered "stream". This eliminates HTTP-level HOL blocking.
HPACK Header Compression
HTTP/2 uses HPACK, a purpose-built header compression algorithm. It maintains a dynamic table of previously seen headers on both client and server, sending only indices or diffs for repeated headers. This dramatically reduces overhead — headers like Cookie, User-Agent, and Authorization are often identical across requests.
Server Push
The server can proactively send resources it predicts the client will need (e.g., pushing CSS/JS after receiving an HTML request) using PUSH_PROMISE frames. In practice, this feature was rarely used well and is deprecated in most browsers as of 2022.
Stream Priority
Clients can assign priority weights and dependencies to streams, hinting to the server which resources to send first (e.g., CSS before images). HTTP/2's priority model was complex and inconsistently implemented, leading to a simpler model in HTTP/3.
HTTP/3 — QUIC & UDP
HTTP/3 (RFC 9114, 2022) replaces TCP with QUIC (RFC 9000), a transport protocol built on UDP. QUIC was originally developed by Google and standardized by the IETF.
Key Advantages
QUIC streams are independent. A lost packet on stream A does not block streams B or C — unlike TCP where all streams share one byte sequence.
QUIC merges the transport and TLS handshakes. Returning clients can send data on the very first packet (0-RTT) using cached keys.
Encryption is mandatory and integrated into the transport. There is no unencrypted QUIC. Even packet headers are partially encrypted.
Connections are identified by a Connection ID, not the IP:port 4-tuple. Switching from Wi-Fi to cellular keeps the same QUIC connection alive.
HTTP/1.1 vs HTTP/2 vs HTTP/3
A side-by-side comparison of the three major HTTP versions.
| Feature | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|
| Year | 1997 | 2015 | 2022 |
| Transport | TCP | TCP | QUIC (UDP) |
| Framing | Text-based | Binary frames | Binary frames |
| Multiplexing | No (pipelining, rarely used) | Yes, over single TCP conn | Yes, independent QUIC streams |
| HOL Blocking | HTTP + TCP level | TCP level only | None |
| Header Compression | None | HPACK | QPACK |
| Encryption | Optional (HTTPS) | Effectively required | Always (TLS 1.3 built-in) |
| Connection Setup | TCP + TLS (2-3 RTT) | TCP + TLS (2-3 RTT) | 1 RTT (0-RTT for returning) |
| Server Push | No | Yes (deprecated in browsers) | Yes (rarely used) |
| Connection Migration | No | No | Yes (Connection ID) |
Real-Time: WebSockets & SSE
WebSockets
WebSockets (RFC 6455) provide full-duplex, bidirectional communication over a single TCP connection. The connection starts as HTTP/1.1 and is upgraded via the Upgrade: websocket header.
Upgrade: websocket
Switching Protocols
frames
After the handshake, data flows as lightweight frames (2-14 bytes overhead per frame vs. HTTP headers for each message). WebSockets support text and binary frames, ping/pong for keepalive, and close frames for graceful shutdown.
Server-Sent Events (SSE)
SSE is a simpler, one-way streaming protocol. The server sends events over a long-lived HTTP connection with Content-Type: text/event-stream. The client uses the browser-native EventSource API.
// Server response
Content-Type: text/event-stream
event: update
data: {"price": 42.50}
event: update
data: {"price": 43.10}
SSE supports auto-reconnection with Last-Event-ID and event types. It works over standard HTTP/2, benefiting from multiplexing (many SSE streams on one connection).
SSE vs WebSocket vs Polling
| Feature | Polling | SSE | WebSocket |
|---|---|---|---|
| Direction | Client -> Server | Server -> Client | Bidirectional |
| Protocol | HTTP request/response | HTTP with text/event-stream | Upgraded TCP (ws://) |
| Latency | High (poll interval) | Low (push) | Lowest (push, both ways) |
| Reconnection | Built-in (just poll again) | Auto (EventSource API) | Manual implementation |
| Binary Data | Yes (HTTP body) | No (text only, Base64 workaround) | Yes (binary frames) |
| HTTP/2 Compatible | Yes | Yes (multiplexed) | No (requires HTTP/1.1 upgrade) |
| Best For | Simple, low-frequency updates | Live feeds, notifications, LLM streaming | Chat, gaming, collaborative editing |
gRPC — HTTP/2 RPC Framework
gRPC is a high-performance RPC framework developed by Google. It uses HTTP/2 for transport and Protocol Buffers (protobuf) for serialization by default.
How It Works
(client stub + server interface)
over HTTP/2
Services and messages are defined in .proto files. The protoc compiler generates client stubs and server interfaces in 10+ languages. Calls look like local function calls but execute remotely.
// example.proto
service UserService {
rpc GetUser (UserRequest) returns (UserResponse);
rpc ListUsers (ListRequest) returns (stream UserResponse);
rpc Chat (stream ChatMessage) returns (stream ChatMessage);
}
message UserRequest {
string id = 1;
}
Four Streaming Types
Single request, single response. Like a normal function call.
Client sends one request, server streams back multiple responses.
Client streams multiple messages, server responds once when done.
Both sides stream messages independently over the same connection.
gRPC vs REST
| Aspect | REST | gRPC |
|---|---|---|
| Protocol | HTTP/1.1 or HTTP/2 | HTTP/2 (required) |
| Serialization | JSON (text) | Protobuf (binary) |
| Contract | OpenAPI / informal | Strict .proto schema |
| Streaming | Limited (SSE, chunked) | Native (4 types) |
| Browser Support | Native | Requires gRPC-Web proxy |
| Performance | Good | Better (smaller payloads, binary, multiplexed) |
| Tooling / Debug | Easy (curl, browser) | Harder (needs grpcurl, protobuf decode) |
| Best For | Public APIs, web clients | Internal microservices, high-throughput |
Test Yourself
Retry-After header indicating when the client can try again.Upgrade: websocket and Connection: Upgrade headers. The server responds with 101 Switching Protocols, and the connection transitions to the WebSocket framing protocol.