Skip to main content
networking

HTTP / HTTPS

12 min read
Fully authored

The request-response protocol that runs the web.

In March 1989, Tim Berners-Lee at CERN wrote a proposal titled "Information Management: A Proposal." His boss wrote on the front page: "Vague, but exciting." A year later, Berners-Lee had built three things: a URL scheme (so documents could reference each other), an HTML markup language (so documents had structure), and a small protocol that let one computer ask another for a document. He called that protocol HTTP — HyperText Transfer Protocol. The first version had one method, no headers, no status codes, and transferred exactly one document per connection. It was ~30 lines of specification.

Today HTTP is the transport for effectively the entire internet. Your bank runs on HTTP. Netflix runs on HTTP. gRPC runs on HTTP. Your smart lightbulb runs on HTTP. It moves ~7,500,000 GB/s globally — and every one of those requests is a variation on the same pattern Berners-Lee sketched in 1990: "Hey server, please give me this document. Here's some context. Signed, this client."

Understanding HTTP is not optional if you want to design systems. Every design interview will assume you know: the request lifecycle (what happens betweenyou type a URL and the page renders), the methods (GET vs POST vs PUT vs PATCH vs DELETE — and why idempotency matters), the status codes (what 301 vs 302 vs 307 vs 308 actually mean for cache behavior), headers (Cache-Control, ETag, Content-Encoding), and HTTPS (how TLS wraps HTTP so nobody in the middle can read your bank transfer).

The RFCs

  • Berners-Lee (1991) — "HTTP/0.9" — the original 30-line protocol. One method (GET). One response type (HTML). No headers.
  • RFC 1945 (1996) — HTTP/1.0. Added headers, status codes, more methods. Content-Type made HTTP general-purpose.
  • RFC 2068 (1997) → RFC 2616 (1999) — HTTP/1.1. Persistent connections (keep-alive), chunked transfer, virtual hosting via Host header. Ruled the web for 16 years.
  • RFC 7540 (2015) — HTTP/2. Binary framing, multiplexing, server push. Google's SPDY became the standard.
  • RFC 9114 (2022) — HTTP/3. HTTP over QUIC (UDP-based). Eliminates head-of-line blocking. 0-RTT handshake.

The request lifecycle — what happens when you type a URL

You type https://example.com/page and hit enter. Between that moment and the page rendering, at least 6 distinct network operations happen — and if any one of them is slow, your page is slow. Watch the full request lifecycle:

HTTPS request lifecycle — step 1 of 7
From URL typed to page rendered — every hop, every RTT.
Step 1
DNS
Step 2
TCP
Step 3
TLS
Step 4
HTTP req
Step 5
Server
Step 6
Response
Step 7
Render
Cumulative time (ms) since URL typed
20ms / typical 800ms budget
Step 1: DNS lookup. Browser asks the recursive resolver for example.com's IP. Typical: 10-40ms cold, ~1ms cached.

The critical insight: your page-load latency is the sum of every step above — DNS lookup, TCP handshake, TLS handshake, HTTP request, server processing, response transmission, parsing, rendering. Optimizing any single step (say, TLS session resumption to skip the handshake) speeds up every request that follows. This is why CDNs, HTTP/2, HTTP/3, and 0-RTT TLS exist: compress the timeline.

HTTP methods — the verbs

HTTP is REST's foundation because it's verb-based — the URL is the noun (the resource), the method is what you want done to it. There are 9 methods, but 5 of them do the vast majority of work. Two properties matter for every method: safety (does it modify state?) and idempotency (does calling it N times have the same effect as calling it once?).

MethodSafe?Idempotent?Cacheable?Body?Use for
GETRead a resource. Never has side effects. Cache-friendly.
HEADSame as GET but returns headers only. Check existence or metadata cheaply.
OPTIONSQuery what methods a resource supports. Used for CORS preflight.
POSTCreate new resources. Not idempotent — retries can duplicate. Use Idempotency-Key header if you need retry safety.
PUTUpsert: replace resource entirely or create if absent. Idempotent — retry safe.
PATCHPartial update. Not idempotent unless the update itself is (e.g., 'set field X to value Y').
DELETERemove a resource. Idempotent — deleting twice is same as deleting once.
CONNECTEstablish a tunnel through a proxy. Used for HTTPS through corporate proxies.
TRACEDebug: echo the request back. Usually disabled in production for security.

Idempotency is the property that lets you retry safely. Network blips are constant — a client sends PUT, gets a timeout, and doesn't know if the write landed. If PUT is idempotent, the client just retries; the second call is a no-op if the first succeeded. POST doesn't have this property — retry a "charge card" POST and you charge twice. This is why every payment API in the world uses Idempotency-Key headers to fake idempotency onto POST.

Status codes — what the server says back

Every HTTP response starts with a 3-digit status code. The first digit is the class: 1xx informational (rarely seen), 2xx success, 3xx redirect, 4xx client error, 5xx server error. Understanding the details — especially the redirect codes and the difference between 401 and 403 — is a common interview filter.

Interactive: click any status code
200
2xx Success
OK
When to return
The request succeeded. Standard success response with a body.
Cache behavior
Cacheable if method is safe/idempotent and cache headers permit.

The 301 vs 302 vs 307 vs 308 gotcha — permanence AND method preservation

This is the most common HTTP question in every interview. The 4 redirect codes look interchangeable but they mean subtly different things:

  • 301 Moved Permanently — the resource has movedforever. Browsers cache the redirect. Search engines update their index. Historically, browsers were also allowed to change POST → GET on the redirect (a spec quirk).
  • 302 Found — the resource is temporarily at a different URL. Do not cache. Historically browsers also allowed POST → GET on this one.
  • 307 Temporary Redirect — same as 302, but must preserve the original method. POST stays POST. This is what "temporary redirect" should have always meant.
  • 308 Permanent Redirect — same as 301, but must preserve the original method. POST stays POST. The modern "permanent" redirect.

Modern APIs use 308 when they change a permanent URL and 307 when they want a temporary redirect that preserves POST/PUT method. 301 and 302 still exist but their method-changing behavior is a landmine for POST-based APIs.

Who actually uses which code in production — the interview cheat sheet

The RFCs define semantics. Production systems reveal what those semantics buy in practice. Study this table before the interview — it's what separates candidates who read RFCs from candidates who've operated infrastructure:

CodeReal services using itWhy they picked it
301
Permanent
Google Search canonical redirects · old→new domain migrations · Wikipedia article redirects · Bit.ly (with pixel-tracking hack) · Facebook fb.meLong-term SEO signal (PageRank flows through 301). Browser cache eliminates repeat-lookup cost. When URL is truly permanent, saves origin infrastructure.
302
Found
sysd.link · TinyURL · most URL shorteners · geo-based edge redirects · A/B testing rewrites · session-based landing pages · Amazon product-of-the-dayEvery hit reaches your server. Analytics work. You can rotate destinations. Session state preserved. Default choice for URL shorteners.
307
Temporary + method-safe
Payment gateways (Stripe · PayPal · Adyen mid-checkout POST redirects) · HashiCorp Vault (standby→active node on POST) · Consul + Nomad HA API · older Elasticsearch shard reroutes · OAuth 2.0 authz code exchange (RFC 6749 §3.1.2.5) · Apollo Router (GraphQL POST canary) · Kubernetes API version migrationPOST must stay POST — request body carries payment / auth / write data. 302 would demote it to GET and lose the body (historical browser quirk). 307 guarantees preservation.
308
Permanent + method-safe
GitHub REST v3 → v4/GraphQL migrations · AWS + GCP regional endpoint permanent moves · Cloudflare + Fastly forced HTTPS on API endpoints · Terraform Cloud / HCP resource moves · Kong + Apigee + AWS API Gateway config-driven path migrations · Netlify _redirects · Vercel vercel.json (opt-in 308)Permanent migration of an API where clients may be POST/PUT/DELETE. 301 could silently downgrade the write to GET and cause data loss. 308 makes the move safe.
RFC timeline in 3 lines
  • RFC 2616 (1999): 301/302 ambiguous about method preservation. Real browsers demoted POST→GET on both. Devs relying on POST-preservation got burned silently.
  • RFC 7231 (2014) + RFC 7538 (2015): codified 307 (temporary + method-safe) and 308 (permanent + method-safe). Filled the missing primitives.
  • RFC 9110 (2022): current HTTP semantics spec. Consolidates + clarifies but doesn't change the 4-code taxonomy.
Interview rule of thumb
  • GET-only workload (URL shortener, static-site canonicalization, blog migrations): 301 or 302 based on caching preference. 307/308 add nothing.
  • Anything with POST / PUT / DELETE that might redirect (API gateways, payment flows, admin panels): 307 (temporary) or 308 (permanent). Never 301/302 — you'll silently lose write payloads.
  • Serving both? Use different codes per route. There's no rule that a service uses only one.

HTTP vs HTTPS — what the S actually does

HTTPS is HTTP running on top of TLS instead of raw TCP. Same protocol, same methods, same headers — but the whole thing is encrypted and authenticated. Watch what changes in the request flow:

What TLS adds to HTTP
HTTP (plain)
GET /transfer?amt=1000&to=eve HTTP/1.1
Host: bank.com
Cookie: session=abc123
⚠ Visible to anyone on the wire
  • ISP sees the request
  • Public WiFi eavesdrops
  • Session cookie interceptable
  • Content can be modified in transit
  • Impersonation trivial (spoof DNS → serve fake page)
HTTPS (HTTP over TLS)
🔒 ==========================
   encrypted payload
   (AES-256-GCM)
   7f3a91b2c4d8e0…
🔒 ==========================
✓ Confidential + integral + authentic
  • Encrypted with per-session keys
  • Nobody in the middle can read
  • Modification is detected (MAC)
  • Server identity verified via cert chain
  • Optional: client identity (mTLS)
What's NOT hidden by HTTPS: the destination IP address, the SNI hostname (which server name the client is connecting to), and traffic patterns (sizes, timing). This means your ISP knows you visited example.com but not what page you loaded there. ECH (Encrypted Client Hello) is closing the SNI gap in 2024+.

Three properties come from TLS: confidentiality (nobody in the middle can read the request), integrity (nobody can modify it undetected), and authentication (via certificates, the client knows it's really talking to example.com). Since 2020 essentially all major browsers refuse to load plain HTTP by default; Chrome, Firefox, and Safari all warn users aggressively. HTTPS-everywhere is now the assumption.

Key HTTP headers you must know

Header reference — the ones you must know
Auth
AuthorizationBearer eyJ…
Client credentials — JWT, session token, API key. Sent on every request that needs auth.
WWW-AuthenticateBearer realm="api"
Server telling client on 401: 'here is how to authenticate.'
Cache
Cache-Controlpublic, max-age=3600, s-maxage=86400
How long clients + intermediaries may cache. s-maxage is CDN-specific.
ETag"a1b2c3d4"
Version identifier for a resource. Client sends back as If-None-Match on next request → 304 if unchanged.
Last-ModifiedWed, 20 Nov 2024 15:04:23 GMT
Timestamp of last change. Older cache mechanism than ETag but still supported.
VaryAccept-Encoding, User-Agent
Which request headers cache should key on. Vary: * means never cache.
Content
Content-Typeapplication/json; charset=utf-8
Body format. JSON, HTML, PNG, whatever. Wrong Content-Type breaks parsers.
Content-Encodinggzip / br
Body compression. gzip = ~70% smaller. br (Brotli) = ~85% smaller, HTTPS-only.
Content-Length3427
Body size in bytes. Required for HTTP/1.1 unless Transfer-Encoding: chunked.
CORS
Originhttps://app.example.com
Client tells server which origin it came from. Required for cross-origin requests.
Access-Control-Allow-Originhttps://app.example.com
Server tells client: 'yes, requests from this origin are OK.'
Meta
Hostexample.com
Virtual hosting — which website is being requested. Required in HTTP/1.1.
User-AgentMozilla/5.0 …
Client identifier. Used for analytics, compatibility hacks, sometimes rate-limiting.
Rate limit
X-RateLimit-Limit1000
Non-standard but widely used. Tells client the request quota per window.
Retry-After60
On 429 or 503: 'try again in N seconds.' Both int-seconds and HTTP-date formats accepted.
Security
Strict-Transport-Securitymax-age=31536000; includeSubDomains
HSTS: browser refuses to talk HTTP for the next year. Guards against downgrade attacks.
Content-Security-Policydefault-src 'self'
CSP: restrict what scripts/styles/images the page may load. Guards against XSS.

HTTP version timeline — a 35-year evolution

HTTP evolution
HTTP/0.91991 · Berners-Lee
Innovation: The original — one document at a time.
Killer bottleneck: One request per connection · GET only · No headers
HTTP/1.01996 · RFC 1945
Innovation: Added headers, methods (POST/HEAD), status codes, Content-Type.
Killer bottleneck: Still one request per connection · No Host header (no vhosts)
HTTP/1.11997-1999 · RFC 2616
Innovation: Persistent connections (keep-alive) · Chunked encoding · Host header (virtual hosting). Ruled the web for 16 years.
Killer bottleneck: Head-of-line blocking on pipelines · One connection per host (browsers open 6+ to compensate)
HTTP/22015 · RFC 7540 (from Google SPDY)
Innovation: Binary framing · Multiplexing (many streams per connection) · Header compression (HPACK) · Server push.
Killer bottleneck: TCP head-of-line blocking · Server push proved counter-productive
HTTP/32022 · RFC 9114 (over QUIC)
Innovation: Runs on QUIC (UDP-based) → eliminates TCP head-of-line blocking · 0-RTT handshake · Connection migration across networks.
Killer bottleneck: Middleboxes still occasionally block UDP · CPU cost for encryption

Applied in real systems

HTTP is the connective tissue. Every system below made explicit choices about which HTTP version, which methods, which cache headers.

Cloudflare
Deep dive

Cloudflare — HTTP/3 at the edge

Cloudflare terminated ~20% of the world's HTTP traffic in 2024. They were among the first to deploy HTTP/3 at production scale. Every request lands at a PoP, gets routed via Anycast to the nearest data center, and proxies over HTTP/2 or HTTP/3 to the origin. Reader can see this in cf-cache-status and alt-svc headers on any Cloudflare-fronted site.

Read the deep dive →
REST APIs
Deep dive

REST — HTTP as the semantic model

Roy Fielding's 2000 PhD thesis defined REST as an architectural style using HTTP verbs as first-class operations. Almost every modern API — Stripe, GitHub, Twilio, AWS — follows this. GET reads, POST creates, PUT upserts, DELETE removes. Idempotency-Key headers make POST safe to retry.

Read the deep dive →
gRPC
Deep dive

gRPC — HTTP/2 as an RPC substrate

gRPC uses HTTP/2 as its wire protocol — protobuf-encoded messages in HTTP/2 frames. Bidirectional streaming works because HTTP/2 supports it natively. Every gRPC call is technically an HTTP/2 request, but with binary protobuf instead of JSON.

Read the deep dive →
Nginx
Deep dive

Nginx — the HTTP reverse proxy

Nginx runs on 30%+ of all internet-facing web servers. Every enterprise reverse proxy, load balancer, and API gateway is either Nginx or an Nginx-alike. Understanding nginx.conf's upstream, location, and cache directives is core networking knowledge.

Read the deep dive →
GitHub API
Deep dive

GitHub REST API — the reference REST design

GitHub's API is widely considered the reference for clean REST design. Resources at /repos/:owner/:repo/issues, methods for each operation, ETag for conditional GETs, X-RateLimit-* headers, pagination via Link header. Read the API docs as a case study.

Read the deep dive →
CDN Cache-Control
Deep dive

CDN cache — how Cache-Control drives the internet

Every CDN — Cloudflare, Fastly, Akamai, AWS CloudFront — respects the Cache-Control header the origin sets. Get this right and cache hit rates hit 95%+. Get it wrong and every request hits your origin. The dance of s-maxage, stale-while-revalidate, and Vary is a whole discipline.

Read the deep dive →

Key takeaways

  • Every HTTP request is DNS lookup → TCP handshake → (TLS handshake if HTTPS) → HTTP request → server processing → response → parse → render. Latency = sum of all steps.
  • HTTP methods split by safety (does it modify state) and idempotency (can I retry safely). GET/HEAD/OPTIONS are safe; GET/PUT/DELETE are idempotent; POST is neither.
  • For redirects: 301 = permanent + may change method, 302 = temporary + may change method, 307 = temporary + method-preserving, 308 = permanent + method-preserving. Use 307/308 for modern APIs.
  • 401 vs 403: 401 "I don't know who you are" (please authenticate); 403 "I know who you are, you can't do this" (permission denied). Get this right on your APIs — clients handle them differently.
  • HTTPS = HTTP over TLS. Same protocol, wrapped in confidentiality + integrity + authentication. As of 2024 essentially all major browsers require HTTPS by default.
  • The big cache headers are Cache-Control, ETag, Last-Modified, Vary. Together they let a CDN serve 95%+ of your traffic without hitting origin.
  • HTTP versions: 0.9 (1991) → 1.0 (1996) → 1.1 (1999) → 2 (2015) → 3 (2022). Each solved the previous version's biggest bottleneck.

References

  • Berners-Lee (1991) — Original HTTP/0.9 proposal at CERN.
  • RFC 2616 (1999) — HTTP/1.1. The definitive version for 16 years.
  • Fielding (2000) — "Architectural Styles and the Design of Network-based Software Architectures." PhD thesis. Defines REST.
  • RFC 7540 (2015) — HTTP/2. Multiplexing over binary framing.
  • RFC 9110 (2022) — HTTP Semantics. The unified modern reference.
  • RFC 9114 (2022) — HTTP/3. QUIC-based transport.
  • Grigorik (2013) High Performance Browser Networking. Free online. The best deep-dive on the request lifecycle.

Practice what you just read

Every foundation concept has a companion quiz to close the loop.