HTTP Fundamentals
How the web actually talks to itself — from a URL in the address bar to a rendered page — written the way we wish someone had explained it before we ever opened devtools' Network tab.
What is HTTP?
HTTP (HyperText Transfer Protocol) is the application-layer protocol that lets a client ask a server for a resource, and lets the server answer — a simple request/response contract that the entire web is built on.
Every time a browser loads a page, calls an API, or fetches an image, it's speaking HTTP. The protocol itself is deliberately simple: a client sends a request (method + URL + headers + optional body), and a server sends back a response (status code + headers + optional body). Everything else — cookies, caching, compression, authentication — is built as conventions on top of this simple exchange.
The defining characteristics
Request/response
Each client-initiated HTTP exchange has one request and one final response. Some exchanges also include interim 1xx responses before the final answer; HTTP/2 briefly added server push, but browser support has largely been removed.
Stateless
The server does not retain any client context between requests. Two requests from the same browser look identical to the server unless the client explicitly sends identifying information (a cookie, a token).
Text-based (originally)
HTTP/1.1 messages are human-readable ASCII text — you can literally telnet into a server and type a raw HTTP request. HTTP/2 and HTTP/3 moved to binary framing for efficiency, but the conceptual model (method, headers, body) stayed the same.
Layered on TCP (or QUIC)
HTTP doesn't handle its own reliability or ordering — it delegates that to TCP (HTTP/1.1, HTTP/2) or QUIC (HTTP/3). This is why understanding TCP's handshake and congestion behavior matters for understanding HTTP performance.
Visual Learning
Watch one request handle construction, server processing, every status-code family, cookies, caching, TLS, and the HTTP/1.1 → HTTP/2 → HTTP/3 evolution as a single continuous system — not fourteen separate explanations.
Why HTTP Was Created
HTTP was invented in 1989–1991 by Tim Berners-Lee at CERN to solve one narrow problem: letting researchers share linked documents over a network. It grew into the protocol running the entire web.
Before HTTP, sharing documents meant FTP, email attachments, or physically walking a tape to another building. Berners-Lee wanted hyperlinked documents — click a link, jump to another document, possibly on another machine. HTTP/0.9 was almost comically simple: a client sent GET /page.html and the server sent back raw HTML. No headers, no status codes, no methods other than GET.
HTTP/1.0 (1996) added headers, status codes, and other methods. HTTP/1.1 (1997, still widely deployed, especially for APIs and behind proxies, and now specified in RFC 9112) added persistent connections, chunked transfer encoding, and the Host header — which is what makes virtual hosting (many domains, one IP) possible.
Anatomy of a Request
Every HTTP request has four parts: a method, a URL, a set of headers, and an optional body.
Method
Declares the intent: GET (read, safe, no side effects), POST (create / submit, has side effects), PUT (replace a resource), PATCH (partially update), DELETE (remove), HEAD (like GET but headers-only), OPTIONS (ask what's allowed — used for CORS preflight).
URL
Scheme (http/https) + host (api.example.com) + path (/users/42) + optional query string (?sort=name). The Host header (not the URL line itself) is what actually tells the server which domain the request is for — critical for shared hosting where one IP serves many domains.
Headers
Key-value metadata: Content-Type, Authorization, Accept, User-Agent, Cookie, Cache-Control. Headers are how almost every HTTP feature beyond the basic request/response is implemented — content negotiation, auth, caching, and CORS are all just headers.
Body
Optional payload — JSON, form data, a file upload. GET requests conventionally have no body (though technically allowed, most servers/proxies ignore it). POST/PUT/PATCH typically carry a body.
Anatomy of a Response & Status Codes
A response has a status line, headers, and an optional body — the status code is the single most important field, telling the client what happened in one number.
1xx — Informational
Rarely seen directly. 100 Continue tells a client it can proceed with sending a large body.
2xx — Success
200 OK (standard success), 201 Created (a POST created a resource), 204 No Content (success, nothing to return).
3xx — Redirection
301 Moved Permanently (cached by browsers — use for permanent URL changes), 302 Found / 307 Temporary Redirect (not cached the same way), 304 Not Modified (cache validation — no body sent).
4xx — Client Error
400 Bad Request (malformed input), 401 Unauthorized (missing/invalid auth), 403 Forbidden (authenticated but not allowed), 404 Not Found, 429 Too Many Requests (rate limited).
5xx — Server Error
500 Internal Server Error (unhandled exception), 502 Bad Gateway (upstream server failed), 503 Service Unavailable (overloaded/maintenance), 504 Gateway Timeout.
# --- client request ---
GET /users/42 HTTP/1.1
Host: api.example.com
Accept: application/json
# --- server response ---
HTTP/1.1 200 OK
Date: Tue, 03 Nov 2026 10:00:00 GMT
Content-Type: application/json
Content-Length: 35
ETag: "v7"
Cache-Control: max-age=60
{"id":42,"name":"Ada","plan":"pro"}The request is a request line (method, target, version), headers, a blank line, and no body. The response is a status line, headers, a blank line and then exactly Content-Length (35) bytes of body. Host is the only header HTTP/1.1 requires from the client, and ETag plus max-age=60 are what make the revalidation flow in the caching section possible: after 60 s the client can send If-None-Match: "v7" and receive a body-less 304.
Browser Caching
The fastest network request is the one you never make. HTTP caching lets browsers reuse previous responses instead of re-fetching them.
Cache-Control: max-age
Tells the browser it can reuse the response for N seconds without asking the server at all — a full cache hit, zero network round trips.
ETag / If-None-Match
Once max-age expires, the browser can revalidate: send the cached ETag in an If-None-Match header. If the content hasn't changed, the server replies 304 Not Modified with no body — cheap for both sides.
Last-Modified / If-Modified-Since
A coarser alternative to ETag — based on a timestamp instead of a content hash. Less precise (second-level granularity) but simpler to generate.
HTTPS & TLS
HTTPS is HTTP running over TLS (Transport Layer Security) — same protocol, an encrypted tunnel underneath.
TLS provides three guarantees: confidentiality (no one on the network path can read the traffic), integrity (no one can tamper with it undetected), and authentication (the client can verify it's really talking to the domain it thinks it is, via the server's certificate, signed by a trusted Certificate Authority).
HTTP/1.1 → HTTP/2 → HTTP/3
Each newer HTTP version targeted a bottleneck in the previous generation, though newer does not automatically mean faster in every real-world network.
HTTP/1.1 (1997)
One request per connection at a time (unless pipelining, which was never reliably deployed). Browsers work around this by opening ~6 parallel TCP connections per host — still limited, and each connection pays its own TCP + TLS handshake cost.
HTTP/2 (2015)
Introduces multiplexing — many requests share a single TCP connection as interleaved binary frames. This removes the HTTP/1.1 request queueing problem on a connection, adds header compression (HPACK), and standardized server push, though server push is now effectively retired in browsers and many deployments.
HTTP/3 (2022)
Replaces TCP with QUIC, a transport built on UDP. Each stream is independent at the transport level, so a single lost packet only stalls its own stream — eliminating TCP-level head-of-line blocking, which matters most on lossy mobile networks. QUIC also folds the transport and TLS handshake into fewer round trips.
Serving HTTP at Scale
A production HTTP service is never one server talking to one client — it's a topology designed for redundancy and throughput.
Reverse proxy
Sits in front of application servers, terminating TLS, handling compression, and forwarding requests — nginx and Envoy are common examples.
Load balancer
Distributes incoming requests across multiple healthy backend instances using a strategy like round-robin or least-connections, and removes unhealthy instances via health checks.
Horizontal scaling
Adding more app server instances (rather than a bigger single machine) to handle more traffic — cheaper, more resilient, and what load balancers are designed to enable.
- HTTP is a stateless request/response protocol — statefulness is bolted on via cookies/tokens.
- Status codes communicate outcome in one number: 2xx success, 3xx redirect, 4xx client error, 5xx server error.
- Caching (Cache-Control, ETag) avoids network round trips entirely — the fastest request is the one never made.
- HTTPS/TLS guarantees confidentiality, integrity, and server authentication — not site trustworthiness.
- HTTP/2 fixed app-level head-of-line blocking with multiplexing; HTTP/3 fixed transport-level blocking with QUIC.
- Production HTTP always sits behind a load balancer / reverse proxy for redundancy and horizontal scale.