Reference notes.

HTTP (Hypertext Transfer Protocol) is the application-layer protocol for the web. It’s evolved from a simple text protocol to a binary, multiplexed, encrypted-by-default system.

Evolution

VersionYearTransportKey Feature
HTTP/1.01996TCPOne request per connection
HTTP/1.11997TCPPersistent connections, pipelining
HTTP/22015TCPBinary framing, multiplexing
HTTP/32022QUIC (UDP)No head-of-line blocking, 0-RTT

HTTP/1.1

Still widely used. Key features over 1.0:

  • Persistent connections (Connection: keep-alive) — Reuse TCP connections for multiple requests, avoiding the cost of repeated handshakes
  • Chunked transfer encoding — Stream responses of unknown length
  • Host header — Required, enabling virtual hosting (multiple domains on one IP)
  • Pipelining — Send multiple requests without waiting for responses. Rarely used in practice due to head-of-line blocking (a slow response blocks all subsequent ones)

Head-of-Line (HOL) Blocking

HTTP/1.1’s fundamental limitation. Responses must be returned in request order. If the first response is slow, all subsequent responses are blocked. Workarounds:

  • Domain sharding — Spread resources across subdomains to open more TCP connections (typically 6 per domain)
  • Bundling — Concatenate CSS/JS files to reduce request count
  • Spriting — Combine images into a single sprite sheet

These are anti-patterns in HTTP/2+ (actually harmful due to cache invalidation and unnecessary data transfer).

HTTP/2

Binary protocol defined in RFC 9113. Maintains HTTP semantics (methods, headers, status codes) but changes the transport framing.

Streams, Frames, and Multiplexing

Single TCP connection
  ├── Stream 1 (GET /index.html)
  │     ├── HEADERS frame
  │     └── DATA frames
  ├── Stream 3 (GET /style.css)
  │     ├── HEADERS frame
  │     └── DATA frames
  └── Stream 5 (GET /app.js)
        ├── HEADERS frame
        └── DATA frames

All requests and responses are interleaved as frames on streams within a single TCP connection. A slow response on stream 1 doesn’t block streams 3 or 5 at the HTTP layer.

However, TCP-level HOL blocking remains — if a single TCP packet is lost, all streams stall until it’s retransmitted. This is the fundamental problem HTTP/3 solves.

HPACK Header Compression

HTTP headers are repetitive (same cookies, user-agent, etc. on every request). HPACK compresses headers using:

  • Static table — 61 common header name-value pairs (:method: GET, :status: 200, etc.)
  • Dynamic table — Previously seen headers, indexed by both sides
  • Huffman encoding — Literal values are Huffman-encoded

Typical compression ratio: 85-95% for repeated requests.

Server Push

Server can proactively send resources before the client requests them (e.g., push style.css when /index.html is requested). Rarely used in practice — difficult to implement correctly, often wasteful (pushes resources already cached by the client). Deprecated in Chrome (2022).

Stream Prioritisation

HTTP/2’s original prioritisation used stream dependencies and weights (RFC 7540). Complex and inconsistently implemented; replaced by the simpler Extensible Priorities scheme (RFC 9218), which defines a version-independent Priority header plus reprioritisation frames for both HTTP/2 and HTTP/3.

HTTP/3

Runs over QUIC instead of TCP. Defined in RFC 9114. Adoption as of 2025: ~35% of web traffic, supported by 95%+ of browsers.

QUIC Transport

QUIC is a general-purpose transport protocol running over UDP:

  • Integrated TLS 1.3 — Encryption is mandatory and built into the protocol, not layered on top. Reduces handshake from TCP + TLS (2-3 RTT) to 1 RTT (0-RTT on resumption).
  • Independent streams — Each QUIC stream has its own flow control. A lost packet on one stream doesn’t block others — eliminating TCP’s head-of-line blocking.
  • Connection migration — Connections are identified by a Connection ID, not the 4-tuple (source/dest IP+port). When a device switches from WiFi to cellular, the connection survives without re-handshaking.
  • Improved loss recovery — QUIC uses packet numbers (never reused, unlike TCP sequence numbers) and supports more precise RTT measurement.

QPACK Header Compression

Replaces HPACK. Designed for QUIC’s out-of-order delivery — HPACK assumed ordered delivery (TCP). QPACK uses separate unidirectional streams for the header table, avoiding HOL blocking from header compression state.

0-RTT

On repeat connections, QUIC can send application data in the first packet. Same replay caveats as TLS 0-RTT — only safe for idempotent requests.

When HTTP/3 Helps Most

  • High-latency connections — Fewer round trips to establish connection
  • Lossy networks (mobile, WiFi) — No HOL blocking on packet loss
  • Connection migration — Mobile users switching networks
  • Many small requests — 0-RTT saves a full round trip

Adoption

All major browsers support HTTP/3. CDNs (Cloudflare, Akamai, Fastly) enable it by default. Server support: nginx 1.25+, Caddy (default), HAProxy 2.6+. Standards: RFC 9114 (HTTP/3), RFC 9000 (QUIC), RFC 9001 (QUIC-TLS), RFC 9204 (QPACK).

Fallback: HTTP/3 is negotiated via the Alt-Svc header or HTTPS DNS record. If UDP is blocked (some corporate networks), clients transparently fall back to HTTP/2 over TCP.

Request and Response Structure

Request

METHOD /path HTTP/1.1
Host: example.com
Header-Name: Header-Value

[Optional body]

Response

HTTP/1.1 200 OK
Header-Name: Header-Value

[Optional body]

HTTP Methods

MethodIdempotentSafeUse
GETYesYesRetrieve resource
HEADYesYesGET without body
POSTNoNoCreate resource, submit data
PUTYesNoReplace resource entirely
PATCHNoNoPartial update
DELETEYesNoRemove resource
OPTIONSYesYesCORS preflight, capabilities
CONNECTNoNoEstablish tunnel (for proxies)
TRACEYesYesLoop-back diagnostic

Idempotent = repeating the request has the same effect. Safe = doesn’t modify server state.

Status Codes

1xx Informational

  • 100 Continue — Proceed with request body
  • 101 Switching Protocols — Protocol upgrade (e.g., WebSocket)

2xx Success

  • 200 OK — Request succeeded
  • 201 Created — Resource created (typically POST/PUT)
  • 204 No Content — Success with no response body

3xx Redirection

  • 301 Moved Permanently — Resource permanently relocated
  • 302 Found — Temporary redirect (may change method)
  • 304 Not Modified — Use cached version
  • 307 Temporary Redirect — Temporary, preserves request method
  • 308 Permanent Redirect — Permanent, preserves request method

4xx Client Errors

  • 400 Bad Request — Malformed request
  • 401 Unauthorized — Authentication required
  • 403 Forbidden — Authenticated but not authorised
  • 404 Not Found — Resource does not exist
  • 405 Method Not Allowed — Method not supported for resource
  • 409 Conflict — Request conflicts with current state
  • 422 Unprocessable Content — Semantic errors in request
  • 429 Too Many Requests — Rate limiting

5xx Server Errors

  • 500 Internal Server Error — Generic server failure
  • 502 Bad Gateway — Invalid response from upstream
  • 503 Service Unavailable — Server temporarily overloaded
  • 504 Gateway Timeout — Upstream server timeout

Headers

Request Headers

  • Host — Target host and port (required in HTTP/1.1+)
  • Accept — Acceptable response media types
  • Accept-Encoding — Acceptable compression (gzip, br, zstd)
  • Authorization — Credentials for authentication (Bearer tokens, Basic auth)
  • Cookie — Send stored cookies
  • User-Agent — Client application identifier
  • If-None-Match / If-Modified-Since — Conditional requests (caching)

Response Headers

  • Content-Type — Media type of the body (e.g., application/json)
  • Content-Length — Size of response body in bytes
  • Content-Disposition — Suggest filename for downloads
  • Set-Cookie — Store cookies on client
  • Location — Redirect target URL
  • Cache-Control — Caching directives
  • ETag — Resource version identifier

Security Headers

  • Strict-Transport-Security (HSTS) — Force HTTPS for all future requests
  • Content-Security-Policy (CSP) — Control which resources can be loaded
  • X-Content-Type-Options: nosniff — Prevent MIME type sniffing
  • X-Frame-Options — Prevent clickjacking (superseded by CSP frame-ancestors)
  • Permissions-Policy — Control browser features (camera, geolocation, etc.)

Compression

  • Accept-Encoding: gzip, br, zstd — Client’s supported compression
  • Content-Encoding: br — Server’s chosen compression

Brotli (br) typically achieves 15-25% better compression than gzip for text. Zstandard (zstd) offers similar ratios with faster decompression. Both are widely supported in modern browsers.

CORS (Cross-Origin Resource Sharing)

See CORS for full details.

Controls which origins can access resources:

  • Access-Control-Allow-Origin — Permitted origins
  • Access-Control-Allow-Methods — Permitted methods
  • Access-Control-Allow-Headers — Permitted headers

Preflight — Browsers send an OPTIONS request before “non-simple” cross-origin requests (custom headers, methods other than GET/HEAD/POST, non-simple content types). The server must respond with appropriate CORS headers.

Cookies and Sessions

HTTP is stateless — cookies provide session persistence.

Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict; Path=/

Key attributes:

  • HttpOnly — Inaccessible to JavaScript (XSS protection)
  • Secure — Only sent over HTTPS
  • SameSite — Controls cross-site sending (Strict, Lax, None)
  • Max-Age / Expires — Cookie lifetime
  • Path / Domain — Scope of the cookie

Caching

Caching reduces latency and server load.

Cache-Control Directives

  • public — Cacheable by any cache (CDN, proxy, browser)
  • private — Only browser cache (personalised content)
  • no-cache — Must revalidate with server before use
  • no-store — Never cache (sensitive data)
  • max-age=N — Fresh for N seconds
  • immutable — Never changes (skip revalidation on reload)
  • stale-while-revalidate=N — Serve stale while fetching fresh in background

Validation

  • ETag — Hash-based validation via If-None-Match
  • Last-Modified — Timestamp validation via If-Modified-Since

Both return 304 Not Modified if unchanged, saving bandwidth.

Caching Strategies

  • Cache busting — Version URLs (e.g., app.v123.js) with long max-age + immutable
  • Stale-while-revalidate — Serve stale content immediately while fetching fresh in the background
  • CDN caching — Edge servers for geographic distribution. Use Vary and Cache-Control to control CDN behaviour.

See Also

  • TLS — Transport encryption for HTTPS
  • TCP — Transport protocol for HTTP/1.1 and HTTP/2
  • DNS — Name resolution before HTTP connection
  • Load Balancing — L7 load balancers operate at the HTTP layer
  • REST — RESTful API design over HTTP
  • CORS — Cross-Origin Resource Sharing details

References