Status codes

BackendTier 1 · hear it this weekPhase 2 · Make it a store

The server's one-line verdict on every request. 200 means success, 404 not found, 401 unauthorized, 500 server error.

When a request comes back, the caller needs to know in one glance whether it worked and, if not, whose fault it was. A wall of prose in every response would be impossible to handle automatically. Status codes exist as a small shared vocabulary of numbers so any client, cache, or monitor can react correctly, and so you can tell a 500 (the server broke) from a 401 (you are not logged in) without reading the body.

Every response carries a number. The 200s mean success. The 400s mean the request was wrong in some way: 404 the thing doesn't exist, 401 you're not logged in, 403 you're not allowed, 429 you're being rate-limited. The 500s mean the server itself broke.

This one number is how engineers and monitoring tools quickly tell what is going wrong and whose fault it is: the caller's (400s) or the server's (500s).

Pick 'not logged in'. Predict the status code before you send it.
Each send is a real GET /api/status. Open the Network tab to see it.
No requests yet. Pick a scenario and send.
The status code family tells you who owns the problem: 2xx it worked, 4xx your request, 5xx (and 429) the server.
A junior PM, stuck

Someone dropped "checkout is throwing 500s, roll it back" in the incident channel and everyone moved fast. I could not tell from that whether it was a minor blip or a real outage, or whose fault a 500 even is. I did not want to ask a question that made it look like I was not following.

In an incident you do not read status codes one at a time, you read the mix. A 500 is the server's own admission that the failure is on its side, so a wall of them at once is the server breaking for everyone, not one user doing something wrong. Here are twenty lines from the checkout access log across the release window. Do not read them as sentences; scan the code column and watch the proportion change.

Checkout access log, 20 lines across the v2.4.1 release window
2026-03-06T13:01:02Z POST /api/orders 200 user=u_88231
2026-03-06T13:01:20Z POST /api/orders 200 user=u_88452
2026-03-06T13:01:44Z GET /api/orders 200 user=u_88231
2026-03-06T13:02:05Z POST /api/orders 200 user=u_88617
2026-03-06T13:02:31Z GET /api/menu 404 user=u_88104
2026-03-06T13:02:50Z POST /api/orders 200 user=u_88709
2026-03-06T13:03:12Z GET /api/orders 401 user=anonymous
2026-03-06T13:03:30Z POST /api/orders 200 user=u_88231
2026-03-06T13:03:55Z POST /api/orders 200 user=u_88452
2026-03-06T13:04:09ZINFOcheckout deployed version=v2.4.1
2026-03-06T13:04:12Z POST /api/orders 500 user=u_88617
2026-03-06T13:04:14Z POST /api/orders 500 user=u_88709
2026-03-06T13:04:19Z POST /api/orders 500 user=u_88231
2026-03-06T13:04:25Z POST /api/orders 500 user=u_88452
2026-03-06T13:04:31Z POST /api/orders 500 user=u_88104
2026-03-06T13:04:40Z POST /api/orders 500 user=u_88801
2026-03-06T13:04:52Z POST /api/orders 500 user=u_88231
2026-03-06T13:05:03Z POST /api/orders 500 user=u_88617
2026-03-06T13:05:20Z GET /api/orders 200 user=u_88452
2026-03-06T13:05:41Z POST /api/orders 500 user=u_88709

Click a step to see the lines it points at.

Reading a single 500 as the whole story. One 500 is a bug to file; twenty in a minute all starting at a deploy is an outage to roll back. The count and the timing are the signal, not any one line.
Treating every red code as equally bad. A 404 is often a broken link and a 401 is someone not logged in; burning incident minutes on those while a wall of 500s climbs is reading the wrong column.
Not knowing which side a code blames. The 400s are the caller's fault, the 500s are the server's; if you cannot tell them apart you cannot say whether to roll back your code or go check the client.
Reporting "checkout is down" without the read-versus-write detail. The 200 on GET /api/orders means reads are fine; saying everything is down when order history still loads sends eng looking in the wrong place.

Say in the channel: "Confirmed from the access log: POST /api/orders was clean 200s until the 13:04 deploy, then all 500s, which is the server failing on our side, not the customers. GET /api/orders still returns 200, so reads are fine and only placing orders is broken. Agree with the rollback." You read the codes in aggregate and told an outage apart from noise.

"We're seeing a spike in 500s" means the backend is failing and it is urgent. "Lots of 404s" often means broken links.
Error dashboards are largely built on these codes, so knowing them lets you read the room during an incident.

"Checkout's throwing 500s, roll it back."

Appears in Phase 2, Make it a store.