The journey of a web request
You type https://example.com into the address bar and hit Enter. Less than a second later, a page appears. Behind that instant, dozens of systems pass the work along a complex relay. We'll follow that request on its journey — parsing the URL, resolving the name, opening a connection, securing it, sending the request, waiting on the server, and rendering the page — to see the machinery behind that one second.
Step 1 — Parsing the URL
Before anything leaves your machine, the browser breaks the URL into the pieces it needs:
https://example.com:443/products?sort=price#reviews
└─┬─┘ └────┬────┘ └┬┘ └──┬───┘ └───┬────┘ └──┬──┘
scheme host port path query fragment
From here, the browser works through these pieces in order — starting with host, over in DNS.
Step 2 — DNS (Domain Name System): turning a name into an address
Computers route packets to IP addresses, not to example.com. So the very first thing that has to happen is a DNS lookup — and it's layered, checked in this order, stopping at the first hit:
- Browser cache — did this browser already resolve this host recently?
- Hosts file — a static, manually-edited list of local overrides (
/etc/hostson macOS,C:\Windows\System32\drivers\etc\hostson Windows). If a name matches here, it wins outright — no cache, no network round trip, nothing to expire:This is also how developers point a domain at127.0.0.1 localhost 255.255.255.255 broadcasthost ::1 localhost127.0.0.1for local testing, or how some ad/malware blockers work — by redirecting known-bad hostnames to0.0.0.0. - OS cache — did any process locally resolve it before?
- Recursive resolver — usually your ISP's (Internet Service Provider) resolver or a public one like
1.1.1.1(Cloudflare),8.8.8.8(Google),... If it doesn't have the answer cached either, it does the actual walk:- ask a root server (represented by the trailing
.on every hostname, the dot is just always hidden:example.comis reallyexample.com.) → "who handles.com?" → "ask this TLD server." - ask that TLD server → "who is authoritative for
example.com?" → "ask this authoritative server." - ask the authoritative server → "what's the IP for
example.com?" → "it's93.184.216.34."
- ask a root server (represented by the trailing
The result is an IP address, say 93.184.216.34 — that every step from here on actually uses, not the hostname.
Step 3 — Opening a connection: the TCP (Transmission Control Protocol) handshake
With an IP in hand, the browser opens a TCP connection to that server on port 443, since our example uses HTTPS. TCP is the transport-layer protocol under HTTP — it guarantees bytes arrive in order and complete, unlike UDP. Opening one always costs the same fixed exchange, the three-way handshake:
- Client → Server: SYN — "I'd like to start a connection, my starting sequence number is x."
- Server → Client: SYN-ACK — "Got it, here's my own sequence number y, and I acknowledge yours."
- Client → Server: ACK — "Acknowledged."
Step 4 — Securing the data: the TLS (Transport Layer Security) handshake
If the scheme is https (it almost always is today), the browser doesn't send the HTTP request yet. First it negotiates encryption on top of the now-open TCP connection — the TLS handshake. In modern TLS 1.3, this is compressed into essentially one round trip:
- ClientHello — the browser lists cipher suites it supports (the algorithms for encrypting data later), and separately, guesses which key-exchange group the server prefers, generates a throwaway key pair for it, and sends only the public half as its key share.
- ServerHello + certificate + key share — the server picks a cipher suite, generates its own throwaway key pair for that same group, sends back its public key share, and attaches its certificate.
- The browser checks the certificate against a trusted certificate authority. Separately, each side combines its own private key with the other's public key share to land on the same symmetric session key — without that key ever crossing the wire.
From here on, everything, including the HTTP request itself, is run through the cipher suite agreed on above — encrypted with the symmetric session key — before being wrapped in a TLS record, so anyone sniffing the connection just sees opaque bytes.
Step 5 — Sending the HTTP request
Only now does the actual HTTP request go out, over the connection that steps 3 and 4 just built:
GET /products?sort=price HTTP/1.1
Host: example.com
Accept: text/html
Cookie: session=abc123
A request line (method, path, version) plus headers — no body for a GET. This is the cheapest step of the whole journey: one small packet, no round trip of its own, because it just rides the connection that's already open and encrypted.
Step 6 — What the server does with it
The request arrives at a machine, but rarely hits application code directly. A typical path:
- A reverse proxy / load balancer (nginx, an ALB, Cloudflare) terminates the connection and picks which backend instance handles it.
- The application server finally puts
pathandqueryto work. It routespathto a handler, readsqueryto shape the response, runs the business logic, and — most of the time — talks to a database or cache to gather what it needs. - A response gets assembled: a status code, headers, and a body.
This is usually the slowest single step in the whole journey, and the one most within your control as a developer — everything before it is protocol overhead you can only minimize, not skip.
Step 7 — The response comes back
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 8241
Cache-Control: max-age=300
<!doctype html>...
A status code tells the browser how to treat what follows: 2xx render it, 3xx follow the Location header somewhere else, 4xx/5xx show an error. Headers like Cache-Control decide whether the next visit can skip several of the steps above entirely.
Putting the whole trip on one timeline
Laid end to end, here's roughly where the time actually goes for a cold connection to a server on the other side of the world — before your framework, your bundle size, or your database query even enter the picture:
Notice how much of it — DNS, TCP, TLS — is spent before the request you actually care about is even sent. None of that is negotiable per request; it's the fixed cost of talking to a server you don't already have an open, secure connection to.
The response landing doesn't mean the TCP connection tears down — that happens at one of a few distinct points:
Connection: close— either side asks to shut it down right after this response (the HTTP/1.0 default).- Idle timeout — nothing else comes through within a window the server configures (commonly 5–60 seconds), so it closes the connection itself.
- Client pool eviction — the browser caps how many idle connections it keeps per host and overall, and closes the oldest ones to make room.
Step 8 — The browser renders the page
The bytes that came back are just text and markup until the browser does something with them:
- Parse HTML into a DOM tree as it streams in.
- Parse CSS into a CSSOM tree.
- Combine both into a render tree — the DOM nodes that are actually visible, with their computed styles.
- Layout — compute the exact size and position of every box.
- Paint — turn those boxes into actual pixels on screen.
Why the second visit feels instant
Almost every step above is something a second request can skip:
| Step | First visit | Repeat visit (same session) |
|---|---|---|
| DNS lookup | Full or partial recursive walk | Served from browser/OS cache |
| TCP handshake | New connection, one round trip | Skipped — connection reused (keep-alive) |
| TLS handshake | New handshake, ~one round trip | Skipped — same reused connection |
| HTTP request | Sent in full | Sent in full, but may return 304 Not Modified |
| Server processing | Full work | Possibly served from a cache layer |
| Rendering | Full parse + layout + paint | Same, unless the page itself is cached |
That's the real reason a warm connection to a site you're already browsing feels instant while the very first link you click from a search result takes a beat: the first one is paying almost every cost on this list at once.
References
- MDN — An overview of HTTP
- Cloudflare Learning — What is DNS?
- Cloudflare Learning — What happens in a TLS handshake?
- High Performance Browser Networking — Ilya Grigorik: Building Blocks of TCP
Related
- Configuring DNS records — the other side of step 2: what the records are made of, and how to read
digwhen one looks wrong. - What TCP does after the handshake — step 3 in depth: sequence numbers, backpressure, why a new connection starts slow, and what
TIME_WAITmeans. - HTTP caching, layer by layer — the
Cache-Controlline in step 7, opened up: freshness,304revalidation, browser vs CDN, and why invalidation is the hard part.