Sign in
TodayMapLearnPracticeReview
Library
18 MINcoreNetworking & CommunicationNot started

HTTP — HyperText Transfer Protocol

HTTP is the application-layer protocol that powers the web. It is request-response, stateless, and text-based (in HTTP/1.1). Understanding HTTP methods, status codes, headers, and the evolution from HTTP/1.1 to HTTP/2 to HTTP/3 is fundamental to every web system design.

Why this matters

Every web API, every browser request, every microservice communication (over REST) uses HTTP. Knowing its semantics — what methods are safe vs idempotent, what status codes mean, how headers affect caching — is non-negotiable for system design. A misunderstanding of HTTP idempotency can cause double charges in a payment system.

Prerequisites
  • How the Internet Works
Related
  • TCP — Transmission Control Protocol
  • REST — Representational State Transfer
  • TLS — Transport Layer Security
Used in
  • API Design
  • gRPC — Google's RPC Framework
  • Real-Time Communication Overview
  • REST — Representational State Transfer
  • Server-Sent Events (SSE)
  • TCP — Transmission Control Protocol
  • TLS — Transport Layer Security
  • WebSockets — Full-Duplex Real-Time Over TCP
Lesson

How it works

HTTP is a request-response protocol: a client sends a request, the server sends a response. It is stateless — each request is independent, and the server doesn't remember previous requests (unless you add cookies or sessions).

This statelessness is both a strength and a weakness: it makes HTTP easy to scale (any server can handle any request) but means the application must manage state through other means (cookies, tokens, server-side sessions).

HTTP methods and their semantics:

MethodSafe?Idempotent?Purpose
GETYesYesFetch a resource. No side effects. Cacheable.
POSTNoNoCreate a resource. Side effects, not idempotent.
PUTNoYesReplace a resource. Same request twice = same state.
DELETENoYesRemove a resource. Second delete returns 404 but state is same.
PATCHNoMaybePartially update. Idempotent if it's 'set to X', not if it's 'increment by 1'.

Safe methods have no side effects — calling them doesn't change server state. They can be cached and prefetched.

Idempotent methods can be safely retried — doing them once or 100 times produces the same result. This matters for unreliable networks: if a request times out, you can safely retry idempotent methods but not non-idempotent ones.

Why idempotency is critical for payments

If a network blip causes your payment request to time out, should you retry? If the method is idempotent (PUT, DELETE), yes — retrying is safe. If it's POST (not idempotent), retrying might charge the user twice. This is why payment APIs use idempotency keys: the client sends a unique ID with each request, and the server deduplicates. Stripe, Square, and Adyen all use this pattern. Without it, retries would be unsafe.

HTTP status codes tell the client what happened:

  • 2xx Success: 200 OK, 201 Created, 204 No Content
  • 3xx Redirect: 301 Moved Permanently, 304 Not Modified (cache hit — don't re-download)
  • 4xx Client error: 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests
  • 5xx Server error: 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout

In system design, 429 (rate limited) and 503 (unavailable) are especially important — they signal the client to back off or retry. Always include a Retry-After header with 429 so the client knows how long to wait.

Common mistakes:

  • Returning 200 OK with an error body. This breaks HTTP semantics and client error handling. Use 4xx/5xx.
  • Returning 500 for client errors (bad input). Use 400.
  • Not returning 201 Created when a resource is created.

HTTP version evolution:

HTTP/1.1 (1997): text-based protocol. One request per TCP connection (later, pipelining was added but suffered from head-of-line blocking). Headers sent as plain text on every request (cookies can be several KB). Still the most widely deployed version.

HTTP/2 (2015): binary framing. Multiple requests multiplexed over a single TCP connection — no head-of-line blocking at the HTTP level. Header compression (HPACK) reduces overhead. Server push (deprecated in practice). Adopted by most modern APIs.

HTTP/3 (2022): runs over QUIC (UDP-based). Eliminates TCP head-of-line blocking entirely — if one stream is slow, others aren't blocked. Faster connection setup (0-RTT — can send data on the first packet). Better on mobile networks (survives IP changes). Default in Chrome and Cloudflare.

The semantics (methods, status codes, headers) are the same across versions — only the transport changes. HTTP/3 is backward-compatible with HTTP/2 and HTTP/1.1 at the application layer.

Key HTTP headers for system design:

Caching:

  • Cache-Control: max-age=60 — cache for 60 seconds.
  • ETag: "abc123" — content hash. Client sends If-None-Match: 'abc123' — if unchanged, server returns 304 Not Modified (saves bandwidth).
  • Last-Modified / If-Modified-Since — timestamp-based caching.

Performance:

  • Connection: keep-alive — reuse TCP connection (HTTP/1.1 default).
  • Accept-Encoding: gzip — compress response.
  • Transfer-Encoding: chunked — stream response without knowing total size.

Security:

  • Authorization: Bearer {token} — auth token.
  • Strict-Transport-Security — force HTTPS.
  • Content-Security-Policy — prevent XSS.

Rate limiting:

  • X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset — tell client their quota.
  • Retry-After: 30 — wait 30 seconds before retrying (sent with 429).
Check yourself
interview

Your payment API receives a POST /charges request, but the network times out before you get a response. The user might have been charged, or might not have. What should you do?

Pick one answer.

Check yourself
core

What is the main performance improvement of HTTP/2 over HTTP/1.1?

Pick one answer.

Check yourself
core

Which HTTP status code should you return when a client has sent too many requests and is being rate-limited?

Pick one answer.

How the Internet Works — DNS, TCP, HTTP explained— Supplementary explanation. The NO CAP lesson remains self-contained.

HTTP/1.1 vs HTTP/2 vs HTTP/3 — side by side.

PropertyHTTP/1.1 (1997)HTTP/2 (2015)HTTP/3 (2022)
TransportTCPTCPQUIC (UDP)
Multiplexingnone (1 req per conn, or pipelining with HOL blocking)yes — parallel streams over 1 TCP connyes — independent streams over QUIC
Head-of-line blockingHTTP-level (pipelining) + TCP-levelTCP-level only (one lost packet stalls all streams)none — streams are independent
Connection setupTCP handshake (1 RTT) + TLS (1-2 RTT) = 2-3 RTTsame: TCP + TLS = 2-3 RTT1 RTT (or 0-RTT with resumed session)
Header encodingplain text, sent every requestHPACK compressionQPACK compression (HPACK-like, stream-aware)
Server pushnoyes (deprecated in practice)no
Connection migrationno — new IP breaks the connectionno — same as HTTP/1.1yes — QUIC connection ID survives IP changes
Deployment ubiquityuniversal~98% of websites~30% and growing (Chrome, Cloudflare, Facebook)

The semantics (methods, status codes, headers) are unchanged across all three versions — only the transport and framing change. This is by design: HTTP/3 is fully backward-compatible with HTTP/2 at the application layer.

Idempotency keys in practice. Stripe popularized the pattern: every POST request includes an Idempotency-Key header (a client-generated UUID). The server treats any two requests with the same key as the same logical operation — the second one returns the cached result of the first instead of re-processing.

The flow is:

  1. Client generates a UUID for this logical operation (e.g., 'charge this user $50 for order 1234').
  2. Client sends POST /v1/charges with Idempotency-Key: <uuid>.
  3. Server checks the idempotency store (Redis, DynamoDB, or a DB table): is this key present?
    • If yes → return the stored response.
    • If no → process the request, store the response keyed by the UUID with a TTL (e.g., 24h), return the response.
  4. If the network fails before the client receives the response, the client retries with the same UUID. The server returns the stored response (or returns 'still processing' if the original is in flight).

This converts a non-idempotent POST into a safely-retryable operation. Without it, a network blip during a payment could double-charge the user, or worse, partially charge and partially refund — leaving the system in an ambiguous state that requires manual reconciliation.

The same pattern applies to webhook delivery, background job processing, and any 'do this exactly once' API. The catch: 'exactly once' is impossible in distributed systems; what you really get is 'at-least-once delivery with at-most-once side effect via deduplication.'

Real system: Stripe's idempotency keys

Stripe's API requires (and the SDK auto-generates) an Idempotency-Key header for every POST that has side effects (charges, refunds, transfers). The Stripe SDK stores the key locally and reuses it across retries with exponential backoff. This is what lets Stripe tell its customers 'retry safely on any network error' — they could not say that without server-side deduplication. The keys live in Stripe's idempotency store for 24 hours; longer-lived deduplication requires a customer-supplied key (e.g., order ID) instead. This is the gold standard for any payment, billing, or order API. If you build such an API without idempotency keys, your support team will eventually reconcile double-charges by hand.

Check yourself
interview

You're loading a page with 20 sub-resources over HTTP/2. The connection is on a flaky mobile network with 2% packet loss. Why will switching to HTTP/3 (QUIC over UDP) meaningfully improve page load time, when HTTP/2 already multiplexes?

Pick one answer.

Try this
interview

The original request might have reached the server (and charged the user) just before the 504 — or it might never have reached the server. The client cannot tell. POST is not idempotent, so naive retries can multiply side effects.

Your mobile app calls POST /v1/charges to charge a user $50. The network returns a 504 Gateway Timeout. The user has spotty reception and taps 'Retry' twice. Without idempotency keys, what happens, and how do you fix it?

Engineering mental model

Mental model. Think of HTTP — HyperText Transfer Protocol as a deliberate boundary in a system. The boundary exists because something becomes harder to manage when everything is done in one place: latency, scale, failure isolation, consistency, cost, or team ownership. The useful question is not “what does HTTP — HyperText Transfer Protocol mean?” but “what pressure makes this boundary worth introducing, and what new failure mode does it create?”

Design lens

Before choosing HTTP — HyperText Transfer Protocol, name the workload, the critical user path, the dominant bottleneck, the failure you are trying to absorb, and the trade-off you are willing to accept. If you cannot name those five things, the design is probably premature.

Original NO CAP systems visual for HTTP — HyperText Transfer Protocol.
Image unavailable. Original NO CAP systems visual for HTTP — HyperText Transfer Protocol.
HTTP — HyperText Transfer Protocol: a compact system-thinking visual.— Original NO CAP visual.
curl -i https://api.example.com/v1/http

# Look for:
# - status code
# - latency
# - retryability
# - response size
A minimal engineering sketch for reasoning about HTTP — HyperText Transfer Protocol.

Back-of-the-envelope reasoning

Numerical lens: write down traffic, payload size, read/write ratio, peak multiplier and durability target before choosing a component. The numbers should justify the architecture.

Interactive sandboxdeterministic

Interactive thought experiment: HTTP — HyperText Transfer Protocol

Change the variables below and predict what breaks first in HTTP — HyperText Transfer Protocol. The production lab can later reuse these same inputs.

System pressure6%
Try this

Change one variable at a time. Predict the failure mode first, then move the slider and see whether your mental model matches the simplified system response.

Hint

If you are stuck on HTTP — HyperText Transfer Protocol, start by drawing the request path and marking every network hop, stateful component, queue, cache and failure boundary. Then estimate where the system will saturate.

Check yourself
solid

You increase traffic by 10× in a system using HTTP — HyperText Transfer Protocol. What should you inspect first?

Pick one answer.

Check yourself
interview

Which statement is the safest engineering habit when using HTTP — HyperText Transfer Protocol?

Pick one answer.

Try this
interview

You have dashboards for traffic, latency, errors and saturation. You can change the architecture, but every change has operational cost.

Production scenario: your system uses HTTP — HyperText Transfer Protocol, traffic suddenly spikes, and p99 latency doubles. What is your first move?

Interview drill

Answer this without notes: When would you choose HTTP — HyperText Transfer Protocol, and when would you intentionally avoid it? Mention at least one bottleneck it addresses, one failure mode it introduces, and one alternative. Then quantify the workload you are designing for.

Engineering lens

A useful engineering lens for HTTP - HyperText Transfer Protocol: define the problem it solves, the simpler design that fails first, the constraint that forces you to introduce this concept, and the new failure modes the concept creates.

Numerical sanity check

Back-of-the-envelope reasoning beats fake precision. State your traffic, payload, concurrency and growth assumptions explicitly, then calculate enough to know whether the current architecture is orders of magnitude away from the target.

Check yourself
interview

Do not optimize for a memorized definition. Reason from the workload and failure mode.

Imagine the simplest version of a system using HTTP - HyperText Transfer Protocol. What breaks first as traffic grows by 10×, and what would you change before reaching 100×?

Pick one answer.

Trade-offs

What you gain, what you pay

Pros
  • +Stateless — easy to scale (any server handles any request).
  • +Text-based (HTTP/1.1) — easy to debug with curl, telnet, browser dev tools.
  • +Wide support — every language, every platform, every firewall allows it.
  • +Caching built into the protocol (Cache-Control, ETag).
Cons
  • −Request-response only — not suitable for server push (use WebSockets or SSE).
  • −Text-based HTTP/1.1 is inefficient — headers sent as text every time.
  • −Connection overhead — each TCP connection costs time (mitigated by HTTP/2 multiplexing).
  • −Verbose — JSON payloads are larger than binary protocols (gRPC/Protobufs).
Failure modes

How this breaks in production

  • Head-of-line blocking in HTTP/1.1 (a slow request blocks others on the same connection).
  • Excessive header size — cookies can bloat requests to several KB.
  • Connection exhaustion — too many concurrent connections overwhelm the server.
  • Returning 200 OK for errors — breaks HTTP semantics and client error handling.
Common mistakes

Don't fall into these traps

  • •Using GET for operations with side effects (violates HTTP semantics, breaks caching).
  • •Treating POST as idempotent (it's not — retries can duplicate).
  • •Returning 200 for errors — use proper 4xx/5xx codes so clients can handle them correctly.
  • •Not including Retry-After with 429 responses.
Where you see it

Real systems using this

Every web request.Every REST API.Most microservice communication.
Teardowns

How real systems implement this

  • Stripe API — Uses idempotency keys for all POST requests so clients can safely retry payment operations without double-charging. Documented in their API guide.
  • Cloudflare — Serves HTTP/3 to all clients by default, reducing connection latency globally. Also uses HTTP/2 Server Push (though this is being deprecated).
Interview prompts

Practice saying it out loud

  • Q1What's the difference between HTTP/1.1, HTTP/2, and HTTP/3?
  • Q2Which HTTP methods are idempotent, and why does it matter?
  • Q3How would you design an API to be safely retryable?
  • Q4What status codes do you use for rate limiting? What header should you include?
Research

Further reading & references

System Design Primer
Open source
ByteByteGo — Scale from zero to millions
ByteByteGo
System Design Tutorial
GeeksforGeeks
System Design Roadmap
roadmap.sh
Networking & Communication reference
Reference
Networking & Communication reference
Reference
Networking & Communication reference
Reference
Cloudflare Learning Center
Cloudflare

Core explanations are original NO CAP material. External references are provided for deeper study and standards.

What next?

Mark as understood once the mental model clicks.

Next recommended

TCP — Transmission Control Protocol