System designCore7 min
HTTP
The language almost every service speaks: what a request and a response actually contain, which requests have the same effect when sent twice, what the status codes tell you, and what changed from HTTP/1.1 to HTTP/3.
1 · The message
An HTTP request is a short, readable letter
Take a notes app. Its phone app and its server talk in HTTP, the HyperText Transfer Protocol. When you open note 17, your phone sends a request and the server sends back a response. Stripped of encryption, both are plain text you can read:
One request, one response
GET /notes/17 HTTP/1.1
Host: notes.example
Accept: application/json
Cookie: session=8f3a91
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: private, max-age=60
{ "id": 17, "title": "Groceries", "text": "Milk, eggs" }Part | In the example | What it says |
|---|---|---|
Method | GET | What you want done |
Path | /notes/17 | Which thing you mean |
Headers | Accept, Cookie, Cache-Control… | Everything about the message: formats, who you are, how long it may be kept |
Status | 200 OK | How it went |
Body | The note, as JSON | The content itself; a GET request has none |
That is all HTTP is: a method and a path, some headers, maybe a body, and a response with a status. Everything else on this page is about what those parts mean.
2 · Methods
The method says what you want done, and whether it is safe to repeat
Method | In the notes app | Same effect if sent twice? |
|---|---|---|
GET | Read note 17 | Yes: it changes nothing |
POST | Create a new note | No: twice makes two notes |
PUT | Replace note 17 with this text | Yes: the second time changes nothing more |
PATCH | Change just the title | Not necessarily: it depends on the change |
DELETE | Delete note 17 | Yes: the second time there is nothing left to delete |
The last column has a name. A request is idempotent if sending it twice has the same effect as sending it once. GET, PUT and DELETE are idempotent by definition; POST is not. GET is also safe, HTTP's word for a request that changes nothing; PUT and DELETE change things, so they're idempotent but not safe. Why does it matter? Because replies get lost, and clients retry:
The phone cannot tell whether the first request failed or only its answer did. Retrying a POST made a duplicate. With a payment instead of a note, it charges twice.
So design every write with the question: what happens if this arrives twice? Reads and replacements are fine. For creations and payments, the usual fix is a unique key sent with the request, so the server can recognize a repeat; Idempotency covers it in the building blocks.
3 · Status codes
The first digit of the status tells you whose fault it was
Class | Meaning | Common ones |
|---|---|---|
2xx | It worked | 200 OK, 201 Created, 204 No Content |
3xx | Look elsewhere, or use your copy | 301 and 302 redirects, 304 Not Modified |
4xx | The request was wrong | 400 Bad Request, 401 not signed in, 403 not allowed, 404 Not Found, 409 Conflict, 429 Too Many Requests |
5xx | The server failed | 500 Internal Server Error, 502, 503 Unavailable, 504 Gateway Timeout |
The first digit matters most, because it tells a client what to do next:
- 4xx: fix the request, don't just repeat it. The same bad request will fail the same way. The exception is 429, which means "slow down": wait, then try again.
- 5xx: maybe try again later. The fault is on the server's side, and it may be temporary. Retry carefully, because a struggling server does not need a flood of retries (and remember idempotency).
- 304: use what you have. The client asked whether its saved copy is still current, and it is. No body is sent, which saves the transfer.
4 · State
Every request stands alone
HTTP is stateless: each request carries everything the server needs, and the protocol keeps no memory between one request and the next. So how does the notes app know it is you? You tell it, every time:
After login, the server hands the phone a token in a cookie, and the phone attaches it to every later request. The server looks the token up, or checks its signature, each time.
This is a gift for scaling. Because no request depends on the one before, any server can answer it, which is what lets you run many copies behind a load balancer (see Scalability). The state has not vanished: it lives in the token and in whatever store the server checks it against.
5 · Versions
HTTP/1.1, 2 and 3 say the same things and deliver them differently
Methods, headers and status codes mean the same in every version. What changed is how the bytes travel. A notes app loading 60 small files shows the difference:
Version | How requests travel | The catch it fixed, or left |
|---|---|---|
HTTP/1.1 | One request at a time per connection, as readable text | Browsers open about 6 connections per site to get some parallelism |
HTTP/2 | Many requests interleaved on one connection, in binary, with compressed headers | Runs over TCP, so one lost packet stalls every request on the connection |
HTTP/3 | Over QUIC, which runs on UDP: each request is its own stream | A lost packet stalls only its own request; setup is faster; a connection survives moving from Wi-Fi to mobile data |
Connections a browser opens to one site to fetch 60 files. With HTTP/1.1, each of the 6 handles one file at a time; with HTTP/2 and 3, all 60 share one connection.
All three are in use. As of 2026, nearly every browser supports HTTP/3, yet it still carries a minority of web traffic, and HTTP/2 and 1.1 carry the rest. For design, the lesson is the same as before: fewer connections and fewer round trips make pages faster, and newer versions are mostly ways of getting both.
Check yourself
5 questions
Takeaways
Remember this
- An HTTP exchange is a method and path, headers, an optional body, and a response with a status.
- GET, PUT and DELETE are idempotent; POST is not. Ask of every write: what if this arrives twice?
- The first digit of a status says what to do: 4xx fix the request, 5xx maybe retry later, 304 use your copy.
- HTTP is stateless: every request carries its identity, so any server can answer it.
- HTTP/1.1, 2 and 3 mean the same things; they differ in how many connections and round trips it takes.