Type a URL, press Enter, and a page appears in a few hundred milliseconds. In that blink, a chain of protocols hands off in a strict sequence — the browser resolves a name, routes packets, opens a connection, secures it, exchanges data, and renders. Understanding this chain is the single best foundation for system design: caching, CDNs, load balancers, and latency budgets all live somewhere along this path. This is the walkthrough I give before any "design X" problem.
Here is the journey at a glance — a browser reaching a server through a DNS lookup and a CDN edge:
0. Before the network: the URL and HSTS
Before a single packet leaves your machine, the browser parses the URL into scheme, host, port, and path, and consults its HSTS (HTTP Strict Transport Security) list. If the host is on that list, the browser silently upgrades http:// to https:// itself — no insecure request is ever sent. It also checks its own caches (memory and disk) in case the whole response is already there. Only then does it need an address.
1. DNS: turning a name into an address
Computers route by IP address, not by names like example.com. So the first step is a DNS lookup that translates the hostname to an IP.
The browser asks a recursive resolver (usually run by your ISP, or a public one like 1.1.1.1). If the answer is not already cached, the resolver walks the hierarchy: a root name server points it to the TLD server for .com, which points it to the domain's authoritative name server, which returns the record. The common record types are A (IPv4), AAAA (IPv6), and CNAME (an alias to another name). The resolver caches the answer for its TTL, so the next lookup is instant — and modern browsers can send the query over DNS-over-HTTPS (DoH) so the lookup itself is private.
DNS is mostly a caching system
A cold DNS lookup can touch several servers, but in practice the vast majority are served from cache — your OS, the browser, and the recursive resolver all cache by TTL. That is why DNS rarely dominates latency in steady state, and why a low TTL (faster failover) trades off against more lookups. Naming the TTL trade-off is a nice signal in an interview.
2. Getting the packets there: IP, routing, and NAT
With an IP in hand, the data has to actually reach it. Your packets hop across a series of routers, each forwarding toward the destination network using IP. On your local network, ARP maps the next-hop IP to a hardware (MAC) address, and NAT on your home router rewrites your private address to a public one so replies find their way back. You rarely think about this layer, but it is where physical distance turns into latency: every router hop and every kilometer of fiber adds time, which is the whole reason we push servers closer to users.
3. TCP: a reliable connection
The browser opens a TCP connection to that IP. TCP gives you a reliable, ordered byte stream over an unreliable network — it handles retransmission, ordering, and flow control so the layers above it do not have to.
Establishing it takes a three-way handshake:
Browser ── SYN ──▶ Server "let's talk; my sequence number is X"
Browser ◀─ SYN-ACK ─ Server "ok; mine is Y, and I ack X"
Browser ── ACK ──▶ Server "ack Y; we're connected"
That is one full round trip before any application data moves. There is a second, subtler cost: TCP slow-start. To avoid swamping the network, TCP begins with a small congestion window and ramps up over several round trips, so a brand-new connection cannot use full bandwidth immediately. That — not just the handshake — is a big reason the first request to a site is slow, and why reusing a warmed-up connection is so much faster.
4. TLS: encryption and identity
For HTTPS, a TLS handshake runs on top of TCP before any HTTP flows. It does two jobs: it authenticates the server and it establishes session keys so the rest of the conversation is encrypted.
In TLS 1.3, the handshake is one round trip: the browser sends a ClientHello (with its key share and, via SNI, the hostname it wants — which is how one IP can serve many HTTPS sites), the server replies with a ServerHello, its certificate chain, and its key share, and both sides derive the same symmetric keys.
A few details a senior engineer names:
- Chain of trust. The server's certificate is signed by an intermediate CA, which is signed by a root CA in the browser's trust store. The browser validates the whole chain — leaf → intermediate → root.
- Forward secrecy. Modern handshakes use ephemeral keys (ECDHE), so even if the server's long-term key leaks later, past sessions cannot be decrypted.
- 0-RTT has a catch. Resumed sessions can send data in the first flight ("0-RTT") for speed, but that early data is replayable, so it is only safe for idempotent requests.
TCP and TLS are separate layers
A common interview slip is to merge them. TCP establishes that two machines can exchange bytes reliably; TLS establishes that those bytes are private and from the right server. HTTPS needs both. HTTP/3 is interesting precisely because it collapses the transport and TLS handshakes into one — more on that below.
5. HTTP: the actual request
Now the browser sends the HTTP request over the encrypted connection — a method, a path, and headers:
GET / HTTP/2
Host: example.com
Accept: text/html
The method carries meaning: GET is safe (no side effects) and GET/PUT/DELETE are idempotent (repeating them is harmless), while POST is neither — which is exactly why retries and 0-RTT are safe for some methods and not others. The server responds with a status line, headers, and a body:
HTTP/2 200 OK
Content-Type: text/html
Cache-Control: max-age=3600
ETag: "a1b2c3"
<!doctype html> ...
Status codes fall into families: 2xx success, 3xx redirects, 4xx client errors, 5xx server errors. And the connection is kept alive — the next request to the same server reuses it, skipping DNS, TCP, and TLS entirely.
6. HTTP caching: the biggest performance lever
Those Cache-Control and ETag headers above are doing the heavy lifting of the web's performance, so they are worth understanding:
Cache-Controltells the browser and any CDN how a response may be reused:max-age=3600(reuse for an hour without asking),no-store(never cache — for private data),private(only the browser, not shared caches),immutable(never revalidate — for fingerprinted assets).- Revalidation with
ETag. When a cached copy'smax-ageexpires, the browser does not blindly re-download. It sends the storedETagback in anIf-None-Matchheader; if nothing changed, the server replies304 Not Modifiedwith no body, and the browser reuses its copy. A round trip, but no payload.
This is the difference between a snappy site and a slow one, and it is where a lot of system-design caching intuition comes from — the same cache → revalidate → origin ladder shows up in front of databases and APIs, not just browsers.
7. HTTP/1.1 vs HTTP/2 vs HTTP/3
The version matters for performance, and the story is really about head-of-line (HOL) blocking — one slow item holding up everything behind it:
- HTTP/1.1 sends one request at a time per connection, so a slow response blocks the next. Browsers worked around it by opening 6+ parallel connections per host.
- HTTP/2 multiplexes many requests as independent streams over a single TCP connection, removing that application-layer HOL blocking. But all those streams still ride one TCP byte-stream, so a single lost packet stalls every stream until it is retransmitted — TCP-level HOL blocking.
- HTTP/3 runs over QUIC (on UDP), where each stream is delivered independently, so a lost packet only stalls its own stream. QUIC also merges the transport and TLS handshakes into a single round trip — a real win on lossy mobile networks.
HTTP/2 over TCP
one byte-stream — a lost packet stalls every stream
Result: all streams stall behind the loss.
HTTP/3 over QUIC
independent streams — loss affects only its own
8. The browser renders the page
Receiving the bytes is not the end — the title promised a page appears. The browser parses the HTML into the DOM, parses CSS into the CSSOM, combines them into a render tree, computes layout (where everything goes), paints pixels, and composites layers onto the screen. CSS and synchronous JavaScript are render-blocking, which is why putting them in the right place — and shipping less of them — is the front-end half of the latency story. (That render pipeline is a whole topic of its own; here the point is just that the network hand-off ends where the rendering pipeline begins.)
Putting it together
Here is the full sequence — DNS, then the TCP handshake, then the TLS handshake, then the HTTP exchange:
The reason this sequence is worth memorizing is that the setup steps are one-time costs. Toggle between a cold first request and a warm repeat (reused connection + cached DNS) and watch DNS, TCP, and TLS disappear:
Request waterfall
interactiveTotal 260ms. The first request pays for DNS, the TCP handshake, and the TLS handshake; a reused keep-alive connection skips all three, which is why connection reuse and CDNs matter so much.
Put numbers on it. Latency has four parts — propagation (distance ÷ speed of light in fiber, ~200,000 km/s), transmission (bytes ÷ bandwidth), processing, and queuing. Propagation dominates over distance: one round trip across a continent is roughly 30–80 ms; within a region, a few ms. A cold HTTPS request to a distant origin spends about one round trip on DNS (if uncached), one on the TCP handshake, one on the TLS 1.3 handshake, then more as slow-start ramps — easily 200–300 ms before useful content over a long link. Move a CDN edge 10 ms away and those handshakes cost a fraction; reuse the connection and the next request pays only the final round trip. That is the entire latency game in one sentence: cut the number of round trips, and shorten each one. (Figures are illustrative — the point is the shape.)
Why this matters for system design
Almost every system-design lever is about shrinking or skipping parts of this path:
- CDNs terminate the connection at an edge near the user (reached via anycast), so the handshakes cross a short distance and cached responses never reach the origin.
- Keep-alive and connection pooling amortize the TCP + TLS cost — and the slow-start ramp — across many requests: the single biggest client-side latency win.
- TLS termination at a load balancer offloads the handshake from application servers.
- HTTP caching (
Cache-Control/ETag) is the samecache → revalidate → originladder you put in front of databases and APIs. - DNS TTLs are your failover knob: low TTL means faster recovery but more lookups.
Master this chain and the rest of distributed systems reads as variations on it. Next, see how the same fundamentals play out when you design a URL shortener or a rate limiter, and how to structure any problem with the system design framework.
Amit Singh is a Senior SDE at Amazon, a Claude Certified Architect, and the founder of AlgoEngineer. We teach these fundamentals live, with mock system-design interviews, in our System Design course.