How a request travels: from typing a URL to seeing the page
Every system you'll ever design is a machine for answering requests. Before choosing databases or caches, you need a clear picture of what one request actually does: who it talks to, in what order, and where the time goes. It turns out most of the time isn't spent computing anything. It's spent waiting for messages to cross the network.
1. The idea
On the internet, the program asking is the client (a browser, a phone app, or another service) and the program answering is the server. They follow a short, fixed sequence every time a client talks to a server it isn't already connected to:
Steps 1–3 only happen when there's no connection yet. A browser keeps the connection open and reuses it for the next requests, which then cost just step 4. That single fact explains a large share of web performance work.
One more idea matters from day one: HTTP is stateless. Each request carries everything the server needs (who you are, usually as a token in a header, and what you want). The server doesn't have to remember the previous request. That's what lets you put many identical servers behind a load balancer and send each request to any of them (Module 08).
2. How it works
Press Play to follow a first visit to https://photos.example.com/photos/42 from a user whose round trip to the data centre takes 60 ms. The bar at the bottom adds up where the time goes. The numbers are realistic but illustrative.
HTTP in sixty seconds
An HTTP request is plain structured text (HTTP/2 and HTTP/3 send the same information in a compact binary form):
GET /photos/42 HTTP/1.1
Host: photos.example.com
Authorization: Bearer eyJhbGciOi... ← who you are (a token, not a user ID you typed)
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: max-age=60 ← how long others may reuse this answer
{"id": 42, "title": "Sunset", "url": "https://cdn.example.com/p/42.jpg"}
| Status | Meaning | Whose fault |
|---|---|---|
| 200 / 201 | OK / Created | Nobody's: it worked |
| 301 / 302 | Moved permanently / temporarily: go to the Location header | Not an error |
| 304 | Not modified: your cached copy is still good | Not an error |
| 400 / 401 / 403 / 404 | Bad request / not signed in / not allowed / not found | The client (4xx) |
| 429 | Too many requests: you're being rate limited | The client (4xx) |
| 500 / 502 / 503 / 504 | Server error / bad gateway / unavailable / gateway timeout | The server (5xx) |
The 4xx vs 5xx split matters in design: clients should not retry most 4xx errors (the request itself is wrong), but may retry 5xx and 429 errors after waiting. You'll build on this in Module 24.
3. Try it yourself
Where does the time go?
Change the user's distance from the server and the conditions of the request. Watch which part of the bar grows. Try a first visit from the other side of the world, then the same request on a reused connection.
Model: DNS miss costs about one round trip to a nearby resolver plus 20 ms; TCP and TLS 1.3 cost one round trip each (TLS 1.2: two); HTTP/3 combines connection and encryption setup into one round trip; transfer assumes a 50 Mbit/s connection and ignores TCP slow start, which makes large first responses slower still.
Measure a real one
Your terminal can show the same breakdown for any website. curl's -w option prints timings (in seconds, measured from the start):
curl -o /dev/null -s -w 'dns %{time_namelookup} tcp %{time_connect} tls %{time_appconnect} first byte %{time_starttransfer} total %{time_total}\n' https://example.com
Run it twice: the second DNS time is usually near zero because the answer was cached. In a browser, open DevTools → Network, click a request, and open the Timing tab for the same picture.
4. Why it matters in design
Round trips beat bandwidth
A faster connection barely helps a small request; fewer round trips and shorter distances do. That's why designs reuse connections, batch requests, and move content closer to users with CDNs and regional servers.
Distance is physics
Light in fibre travels about 200,000 km per second. New York to London (about 5,600 km) is at least 56 ms there and back before any equipment adds delay. No code change fixes that, only moving the data.
Stateless servers scale
If any server can answer any request, you can add servers, remove them and replace broken ones freely. Keep sessions and user data in a shared store, not in one server's memory.
Every hop can fail
DNS, the load balancer, the app server, the database: each is a place where the request can stall or break. Later modules add redundancy, timeouts and retries at each hop.
DNS changes are slow
Resolvers cache answers for the record's TTL (often minutes to hours), so pointing a name at a new server doesn't take effect everywhere at once. Failover that relies on DNS takes at least that long.
HTTPS hides, it doesn't vouch
TLS encrypts the traffic and proves the server's identity. It says nothing about whether the client is honest: anything in the request body can be forged. Identify users from a verified token.
5. In real systems
| Hop | What it usually is | Typical time |
|---|---|---|
| DNS | Your device's cache, then a recursive resolver (your ISP's, or public ones like 1.1.1.1 and 8.8.8.8), which asks the domain's authoritative servers (Route 53, Cloud DNS, Cloudflare and others) | 0 ms cached; tens of ms on a miss |
| CDN edge | CloudFront, Cloudflare, Akamai, Fastly: servers in hundreds of cities that cache content and terminate TLS close to users | A few ms to tens of ms away |
| Load balancer | A managed one (AWS ALB/NLB, Google Cloud Load Balancing, Azure Load Balancer) or software (NGINX, HAProxy, Envoy) | Well under 1 ms added |
| App servers | Your code in containers (often on Kubernetes), virtual machines, or serverless functions | Milliseconds to hundreds of ms |
| Cache | Redis, Valkey or Memcached, in the same data centre | Under 1 ms |
| Database | PostgreSQL, MySQL, DynamoDB and others | About 1–10 ms for an indexed query |
HTTP versions in 2026. HTTP/1.1 sends one request at a time per connection, so browsers open several connections. HTTP/2 sends many requests at once over one connection. HTTP/3 runs over QUIC, which uses UDP and combines the connection and TLS handshakes into one round trip; it also copes better with lossy mobile networks. Most large sites and CDNs serve HTTP/2 and HTTP/3 today. Module 06 goes deeper.
In an interview you rarely draw DNS or TLS. You do need this picture in your head: it tells you why a CDN helps, why a stateless app tier scales, and why a request that calls five services in a row is slow.
The technologies up close
a managed load balancer terminates TLS, routes by path and health-checks the app servers; a CDN sits in front for static content.Mention TLS, keep-alive and anycast only when latency, global users or security come up.
Reverse proxies and ingress
The default front doorA server that sits in front of your app servers and receives every request first: it terminates TLS, routes by host and path, balances load, limits rates, compresses, caches and adds headers. Your app servers never face the internet directly.
How it works
- Terminate, then forward: the proxy decrypts HTTPS, reads the request, picks a backend (by path, host, header or weight) and forwards it over a pooled, kept-alive connection, usually plain HTTP or mTLS inside the network.
- Health checks: it probes backends and stops sending to ones that fail, so a crashed server disappears in seconds.
- Passes the client along: the app only sees the proxy's address, so the proxy adds
X-Forwarded-For/Forwardedheaders; trust them only from your own proxy.
| Product | Known for |
|---|---|
| NGINX | Web server and proxy; static files, simple config, everywhere |
| HAProxy | Very fast L4/L7 load balancing, detailed health checks and stats |
| Envoy | Dynamic config by API (xDS), gRPC, rich metrics; the base of most service meshes and many API gateways |
| Caddy / Traefik | Automatic HTTPS through ACME; Traefik discovers containers and Kubernetes services |
| Cloud load balancers | AWS ALB/NLB, Google Cloud Load Balancing, Azure Application Gateway: managed, no servers to run |
Status today (checked October 2026)
On Kubernetes, the community ingress-nginx controller was retired on 31 March 2026 (no further fixes); new clusters use the Gateway API with an implementation such as Envoy Gateway, Istio, Cilium, NGINX Gateway Fabric or a cloud's own controller. The Ingress API itself still exists.
Use it when
- Always, in front of any public service
- Path routing to several services behind one domain
- Central TLS, rate limits and request logging
Skip it when
- Nothing to skip: the question is only whether it's managed (a cloud LB) or one you run
In the interview
Clients hit a managed L7 load balancer that terminates TLS and routes
/api to the app tier and /static to the CDN origin.
- App servers with public IPs and no proxy in front.
- Trusting X-Forwarded-For from anyone: clients can forge it to dodge IP rate limits.
- A single proxy instance: it needs at least two, behind DNS or a cloud load balancer.
TLS 1.3 and certificates (ACME)
The default · HTTPS everywhereTLS encrypts the connection and proves the server is who it claims to be, using a certificate signed by a trusted certificate authority. TLS 1.3 is the current version: faster and simpler than 1.2.
How it works
- One round trip: the client sends its key share in the first message, so TLS 1.3 needs 1 round trip after TCP (TLS 1.2 needed 2). On a 100 ms path that saves 100 ms per new connection. HTTP/3 over QUIC folds TCP and TLS into one round trip.
- 0-RTT resumption: a returning client can send data in its very first message. Fast, but that data can be replayed by an attacker, so allow it only for safe, idempotent requests like GET.
- Forward secrecy always: every connection uses fresh ephemeral keys, so a stolen server key can't decrypt old recorded traffic.
- Certificates by ACME: a client (certbot, Caddy, cert-manager) proves you control the domain with an
HTTP-01file, aDNS-01TXT record (needed for wildcards) orTLS-ALPN-01, then gets and renews the certificate automatically.
Status today (checked October 2026)
Certificate lifetimes are shrinking by industry rule (CA/Browser Forum ballot SC-081): at most 200 days from 15 March 2026, 100 days from 15 March 2027 and 47 days from 15 March 2029. Let's Encrypt issues 90-day certificates today, offers 45-day ones through an opt-in profile, and plans 64 days by default from February 2027 and 45 days from February 2028. Manual renewal is no longer realistic: automate it.
Use it when
- Every external connection, and ideally internal ones too (mTLS, Module 26)
- TLS terminated at the CDN or load balancer, close to users
Skip it when
- 0-RTT for anything that changes state (payments, orders)
In the interview
TLS terminates at the edge; certificates are issued and renewed automatically with ACME, and traffic to the backends is re-encrypted.
- Manually renewed certificates: shorter lifetimes turn this into an outage waiting to happen.
- 0-RTT enabled for POST requests: replayable.
- Plain HTTP between services on a shared network with no reason given.
Connection reuse: keep-alive and pools
The default · always reuse connectionsOpening a connection costs round trips (TCP, then TLS) and CPU; reusing one costs nothing. Keep-alive keeps HTTP connections open between requests, and connection pools keep a set of ready connections to databases and services.
How it works
- The saving: a new HTTPS connection costs 2 round trips before the first byte (1 TCP + 1 TLS 1.3). At 80 ms per round trip that's 160 ms, more than most requests take to process.
- HTTP/1.1 keeps connections open by default; HTTP/2 and HTTP/3 go further and send many requests at once over one connection.
- Database pools: each PostgreSQL connection is a separate process using several MB, so thousands of app threads must share a small pool, often through PgBouncer or RDS Proxy.
- Idle timeouts must line up: if a backend closes idle connections before the load balancer does, the balancer sometimes sends a request on a connection that's just been closed and returns a 502. Make the backend's keep-alive timeout longer than the balancer's (AWS ALB's idle timeout defaults to 60 seconds; Node.js's server keep-alive default is 5).
Status today
Built into every HTTP client, proxy and database driver; usually you only need to size the pools and align the timeouts.
Use it when
- Every service-to-service and service-to-database call
- Pools sized from the database's connection limit divided by the number of app instances
Skip it when
- Nothing: the only question is the size and timeouts
In the interview
App servers keep pooled connections to the database through PgBouncer, about 20 per instance, so 50 instances stay well under the database's limit.
- A new database connection per request.
- Pools that add up to more connections than the database allows once autoscaling adds instances.
- Intermittent 502s blamed on the network when it's a timeout mismatch.
Anycast and GeoDNS
Situational · global entry pointsTwo ways to send each user to a nearby location. Anycast announces the same IP address from many sites, and internet routing delivers packets to the nearest one. GeoDNS answers the same name with different IP addresses depending on where the user's resolver is.
How it works
- Anycast: every site announces the same prefix over BGP; each router picks the shortest network path. A site that fails stops announcing and traffic shifts to the next nearest within seconds to minutes, with no DNS caching in the way. Used by DNS (the root servers, 1.1.1.1, 8.8.8.8), CDNs like Cloudflare, and AWS Global Accelerator.
- GeoDNS / latency routing: the DNS server looks at where the query comes from and returns the closest region's address (Route 53 latency or geolocation routing, Cloud DNS geo policies). Failover depends on DNS TTLs, and on resolvers honouring them.
- "Nearest" means network-nearest: anycast follows routing policy, not the map, so it's usually but not always the closest site.
Status today (checked October 2026)
You rarely build either: you get anycast from a CDN or a global load balancer, and GeoDNS from a managed DNS service.
Use it when
- Users on several continents
- DNS, CDNs and DDoS absorption (the attack spreads across every site)
- Fast regional failover (anycast)
Skip it when
- A single-region app: one regional load balancer is enough
In the interview
Users reach the nearest edge through the CDN's anycast addresses; the edge routes to the closest healthy region.
- Failover relying on DNS with a 1-hour TTL.
- Assuming anycast keeps a long TCP session on one site: a routing change can move it mid-connection (fine for short requests and DNS; CDNs engineer around it).
6. Remember it
How this hook works: what "Find, knock, lock, ask" means
What the slogan means, word by word
- "Find"
- DNS turns the name into an IP address. Usually cached, so often free; a miss costs a trip to a resolver and maybe beyond.
- "knock"
- The TCP handshake: SYN, SYN-ACK, ACK. One round trip before any data can flow.
- "lock"
- The TLS handshake agrees on keys and checks the server's certificate. One more round trip with TLS 1.3.
- "ask"
- The HTTP request and response, where the server finally does its work. One round trip plus the server's time.
Why this picture fits: it's the order you'd follow visiting a stranger's shop, and it makes the expensive part obvious: three of the four steps are about getting ready to talk.
The story → the concept
| In the story | In the system |
|---|---|
| Looking up the shop's address | DNS resolution (cached for the record's TTL) |
| Knocking and waiting for the door | TCP three-way handshake |
| Agreeing a private language | TLS handshake and certificate check |
| Placing the order | The HTTP request |
| Staying inside for a second order | Connection reuse (keep-alive, HTTP/2, HTTP/3) |
| A branch of the shop on your street | A CDN edge or a regional server |
Watch it on an example
A phone app in Sydney calls an API hosted in Virginia (round trip about 200 ms):
- Find: the phone has the name cached. 0 ms.
- Knock: TCP handshake. 200 ms.
- Lock: TLS 1.3 handshake. 200 ms.
- Ask: request, 30 ms of server work, response. 230 ms. Total about 630 ms before the screen can update.
- The next request on the same connection: just "ask", 230 ms. With an API server in Sydney: about 40 ms.
The trap it saves you from
Optimising the server's 30 ms while ignoring the 600 ms of round trips. "Find, knock, lock, ask" makes you count the trips first.
It still works when…
Services call each other inside your data centre. The steps are the same; round trips are just tiny (well under a millisecond), so there the server's work and the number of calls in a row dominate instead.
7. Common mistakes
8. Design exercise (20 minutes)
- Draw the path. On paper, draw every hop for opening one screen of an app you use daily: client, DNS, CDN, load balancer, app servers, cache, database. Mark which hops are skipped on the second request.
- Count the trips. For a user 150 ms away, estimate the time to the first byte on a first visit with TLS 1.3, then on a reused connection. Then estimate it with HTTP/3.
- Measure three sites. Run the
curlcommand from section 3 against three websites, one of them hosted far from you. Which part of the time is largest for each? - Move the content. Decide which parts of your app's screen could be served from a CDN near the user, and which must come from the origin servers. Say why in one line each.
- Write it down. Three bullets in your design notebook: find–knock–lock–ask, round trips beat bandwidth, stateless servers scale.
9. Self-check quiz
On a first visit to a site far away, what usually takes the most time?
Why does reusing an open connection make the next request faster?
What does making app servers stateless buy you?
Which response is reasonable to retry after a short wait?
How many round trips does a brand-new HTTPS connection (TCP + TLS 1.3) take before the request can be sent?
A service returns occasional 502s behind a load balancer, only on idle connections. Most likely cause?
10. Go deeper
| Resource | Time | Why |
|---|---|---|
| An overview of HTTP (MDN) | 15 min | The clearest short reference for requests, responses, methods and headers. |
| What happens when you type google.com and press Enter | 30 min | The famous, extremely detailed walk-through, from the keyboard to the screen. |
| What is DNS? and What happens in a TLS handshake? (Cloudflare Learning Center) | 20 min | Plain-language explanations with diagrams of the two setup steps. |
| High Performance Browser Networking (Ilya Grigorik, free online) | Chapters 1–4: 2 h | Latency, TCP and TLS explained by the numbers. Older, but the physics hasn't changed. |