How a click becomes a rendered page — networking, HTTP, backend architecture, and auth. Written at junior-dev / interview level.
Before any HTTP happens, two computers must (a) locate each other and (b) open a reliable channel. That's what the network stack does.
| Layer | Job | Unit | Examples |
|---|---|---|---|
| Application | What the data means | Message | HTTP, DNS, SMTP, WebSocket, gRPC |
| Transport | Deliver to the right process, reliably or not | Segment | TCP, UDP, QUIC |
| Network | Route across networks to the right machine | Packet | IP, ICMP, BGP |
| Link | Move bits to the next hop on the wire | Frame | Ethernet, Wi‑Fi, ARP |
Identifies a machine/interface. 142.250.72.14 (IPv4) or 2607:f8b0::200e (IPv6). Private ranges like 10.x, 192.168.x are LAN-only and get translated by NAT.
16-bit number identifying a process on that machine. 80 HTTP, 443 HTTPS, 22 SSH, 5432 Postgres. An IP + port pair is a socket.
The phone book: turns api.example.com into an IP. Runs on UDP/53 (TCP for big answers). Answers are cached per the record's TTL.
Record types worth knowing: A IPv4 · AAAA IPv6 · CNAME alias · MX mail · TXT verification/SPF · NS nameservers.
SYN → SYN-ACK → ACKTLS sits between TCP and HTTP. After the TCP handshake, the TLS handshake:
TLS 1.3 needs 1 round trip (0-RTT on resumption); TLS 1.2 needed 2. TLS gives you three things: confidentiality (encrypted), integrity (tamper-evident), and authenticity (you're talking to the real server).
This is the single most common systems interview question. Click each step.
https://api.example.com:443/v1/users/42?fields=name#bio
└scheme┘ └──── host ────┘ └port┘└── path ──┘└── query ──┘└frag┘
#bio) → never sent to the server; browser-onlyThe browser also checks its HSTS list and may upgrade http:// to https:// before doing anything.
Browser cache → OS cache → recursive resolver → root/TLD/authoritative. Result is cached for the record's TTL. Big sites return an IP near you via GeoDNS / anycast so you hit a nearby CDN edge.
client ──── SYN ────────▶ server
client ◀─── SYN-ACK ──── server
client ──── ACK ───────▶ server (connection established)
One full round trip. This is why latency (RTT) matters more than bandwidth for page load, and why connections are kept alive and reused.
ClientHello → ServerHello + certificate → validate chain → derive session keys. ALPN inside the handshake also decides whether you'll speak HTTP/1.1 or HTTP/2.
GET /v1/users/42 HTTP/1.1
Host: api.example.com
User-Agent: Mozilla/5.0 ...
Accept: application/json
Authorization: Bearer eyJhbGciOi...
Cookie: session=abc123
(blank line ends headers; body would follow)Inside the app: routing matches the path → middleware runs (auth, logging, rate limiting, body parsing) → the handler executes business logic → it reads/writes the database → it serializes a response.
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 74
Cache-Control: private, max-age=60
ETag: "a3f9c1"
{"id":42,"name":"Ada Lovelace","email":"ada@example.com"}Sub-resources (CSS, JS, images, fonts) each trigger their own request — often reusing the same connection. Synchronous <script> blocks parsing; defer/async don't.
HTTP is a stateless, text-based request/response protocol. Stateless means the server remembers nothing between requests — that's why cookies and tokens exist.
| Method | Purpose | Safe? | Idempotent? | Body? |
|---|---|---|---|---|
GET | Read a resource | Yes | Yes | No |
POST | Create / trigger an action | No | No | Yes |
PUT | Replace a resource wholesale | No | Yes | Yes |
PATCH | Partial update | No | Not necessarily | Yes |
DELETE | Remove a resource | No | Yes | Optional |
HEAD | Like GET, headers only | Yes | Yes | No |
OPTIONS | Ask what's allowed (CORS preflight) | Yes | Yes | No |
Safe = doesn't change state. Idempotent = doing it 5 times leaves the same state as doing it once. This is why a retried PUT is fine but a retried POST may double-charge a card — hence idempotency keys.
The classes: 1xx informational · 2xx success · 3xx redirect · 4xx you messed up · 5xx the server messed up.
Host — which site (required in 1.1; enables virtual hosting)Accept — formats the client wantsAuthorization — Bearer <token> or Basic ...Cookie — stored cookies for this originContent-Type — what the body isIf-None-Match — conditional GET using an ETagOrigin / Referer — where the request came fromContent-Type — e.g. application/jsonCache-Control — no-store, max-age=3600, privateETag / Last-Modified — validators for cachingSet-Cookie — create/update a cookieLocation — where a 3xx pointsAccess-Control-Allow-Origin — CORSStrict-Transport-Security — force HTTPS (HSTS)# First request
GET /logo.png → 200 OK
Cache-Control: max-age=86400
ETag: "v3"
# Within 24h: no request at all — served from local cache
# After expiry: revalidate cheaply
GET /logo.png
If-None-Match: "v3" → 304 Not Modified (no body, tiny)
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=1209600
HttpOnly — JavaScript can't read it → blunts XSS token theftSecure — only sent over HTTPSSameSite=Lax|Strict|None — controls cross-site sending → the main CSRF defenseGET /users list
POST /users create → 201 + Location: /users/42
GET /users/42 read → 200 or 404
PUT /users/42 full replace
PATCH /users/42 partial update
DELETE /users/42 remove → 204
GET /users/42/posts nested resource
Principles: nouns not verbs, plural collections, statelessness, correct status codes, use the query string for filtering/sorting/pagination (?page=2&limit=20&sort=-created_at).
| Version | Transport | Key change |
|---|---|---|
| HTTP/1.1 | TCP | Text; keep-alive; head-of-line blocking — one slow response stalls the connection, so browsers open ~6 per origin |
| HTTP/2 | TCP + TLS | Binary framing, multiplexed streams on one connection, header compression (HPACK), server push (now deprecated) |
| HTTP/3 | QUIC over UDP | Removes TCP-level head-of-line blocking, 0/1-RTT handshake, connection survives network switches (Wi-Fi→cellular) |
Client asks every N seconds. Simple, wasteful, laggy.
text/event-stream. One-way server→client push over plain HTTP. Great for feeds and notifications.
HTTP Upgrade → persistent full-duplex socket. Chat, live collaboration, games.
Spreads traffic across replicas (round-robin, least-connections, hash). Removes unhealthy instances. Often terminates TLS. Gives you horizontal scaling and zero-downtime deploys.
No per-user state in memory — session data lives in Redis or a signed token. That's what makes any server able to handle any request, and lets you add/remove instances freely.
Repeated reads are the bulk of traffic. Cache-aside is the common pattern: check Redis → miss → query DB → write to Redis with a TTL. The hard part is invalidation.
Anything slow (email, video encode, report generation) is pushed to a queue so the request returns fast. Buys you retries, backpressure, and smoothing of traffic spikes.
Copies of static assets in hundreds of cities. Cuts latency (physics — distance costs milliseconds) and offloads origin traffic.
Writes go to the primary; reads fan out to replicas. Replication lag means a read right after a write may be stale — eventual consistency.
| Vertical (scale up) | Horizontal (scale out) | |
|---|---|---|
| How | Bigger machine | More machines |
| Limit | Hardware ceiling | Effectively none |
| Complexity | Low — no code change | Higher — needs statelessness, LB, distributed data |
| Failure | Single point of failure | Redundant by design |
Fixed schema, joins, ACID transactions, strong consistency. Default choice for anything with relationships and correctness requirements — money, orders, users.
ACID = Atomicity, Consistency, Isolation, Durability
Flexible documents or wide columns, easy horizontal partitioning, often eventual consistency. Good for huge volume, denormalized reads, unstructured or rapidly-changing shapes.
EXPLAIN and a missing index.When a network Partition happens, a distributed system must choose:
Since partitions will happen, in practice CAP is a choice between consistency and availability.
One deployable. Simple to run, test, and reason about; in-process calls; single transaction boundary. Downside: one codebase, coupled deploys, whole-app scaling.
Independent deploys, per-service scaling, team autonomy, tech diversity. Cost: network calls that fail, distributed transactions, tracing/observability burden, operational overhead.
429 with Retry-After401 vs 403).| Server sessions | JWT (stateless tokens) | |
|---|---|---|
| Where state lives | Server (Redis/DB); client holds an opaque ID | In the token itself, signed |
| Revocation | Instant — delete the row | Hard — valid until expiry unless you keep a denylist |
| Scaling | Needs a shared session store | No lookup; any server can verify |
| Best for | Classic web apps, anything needing instant logout | APIs, mobile, service-to-service |
// A JWT is three base64url parts joined by dots:
header.payload.signature
{"alg":"HS256","typ":"JWT"} // header
{"sub":"42","role":"admin","exp":1790000000} // payload — readable by anyone!
HMACSHA256(base64(header)+"."+base64(payload), secret) // signature
alg server-side — accepting alg: none or a swapped algorithm is a classic vulnerability.Common pattern: short-lived access token (5–15 min) + long-lived refresh token stored in an HttpOnly cookie, rotated on each use.
Key points: the app never sees the user's Google password. OAuth 2.0 = authorization (delegated access to an API); OpenID Connect layers authentication on top by adding an id_token (a JWT describing the user). Public clients (SPAs, mobile) must use PKCE. The state parameter prevents CSRF on the callback.
MD5/SHA-256 — they're built to be fast, which helps attackers.User input concatenated into a query. Fix: parameterized queries / prepared statements. Never string-build SQL.
// bad
"SELECT * FROM u WHERE id=" + id
// good
"SELECT * FROM u WHERE id=$1", [id]Attacker-supplied script runs in another user's page. Fix: escape on output, use a templating engine that escapes by default, set a Content-Security-Policy, mark cookies HttpOnly.
A malicious site makes the browser send an authenticated request to yours using its cookies. Fix: SameSite cookies, anti-CSRF tokens, check Origin.
/orders/1002 returns someone else's order. Fix: authorize every object access server-side. The #1 item on the OWASP Top 10.
Traffic intercepted in transit. Fix: HTTPS everywhere, HSTS, valid certs, no mixed content.
API keys committed to git. Fix: env vars, a secrets manager, rotation, and pre-commit scanning.
The same-origin policy stops JavaScript on a.com from reading responses from b.com. An origin = scheme + host + port; all three must match. CORS is the server's way of opting in:
# Browser preflight for a non-simple request
OPTIONS /api/data
Origin: https://app.example.com
Access-Control-Request-Method: PUT
# Server permits it
204 No Content
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, PUT, POST
Access-Control-Allow-Credentials: true
Nine questions covering the material. Click an answer.
0 / 9 answered