What happens when you open a website
In one line
Section titled “In one line”The browser turns a name into an IP address (DNS), opens a secure connection to it (TCP plus TLS, or QUIC), sends an HTTP request, and renders the response while fetching everything the page refers to.
Why it exists
Section titled “Why it exists”Each layer fixed a specific problem of the one before it.
- IP (1981) moves packets between machines but promises nothing: packets can be lost, duplicated or reordered.
- TCP (1981) adds a reliable ordered byte stream on top of IP.
- DNS (1983) replaced a single
HOSTS.TXTfile that every machine had to download, so people could use names instead of addresses. - HTTP (1991) gave a document format a way to be requested by name.
- TLS (SSL in 1995, TLS 1.3 in 2018) added encryption and proof of who the server is, because the layers below are readable and forgeable by anyone on the path.
- QUIC and HTTP/3 (2021 and 2022) moved transport into user space over UDP to remove delays that TCP cannot fix.
How it works
Section titled “How it works”Example: you type https://example.com/ and press Enter.
- URL parsing. The browser splits the URL into scheme (
https), host (example.com), port (443 by default forhttps) and path (/). If the text is not a URL, it becomes a search query. - HSTS check. If the host is on the HTTP Strict Transport Security list (preloaded in the browser, or remembered from an earlier
Strict-Transport-Securityheader), the browser uses HTTPS without ever trying HTTP. - Cache check. A fresh cached response (
Cache-Control: max-age) is used without any network at all. A stale one is revalidated later withIf-None-Match. - DNS lookup. The browser checks its own cache, then the OS cache and
/etc/hosts, then asks the configured recursive resolver. On a cold cache the resolver walks the tree: a root server, the.comservers, then the authoritative server forexample.com. The answer is an A record (IPv4) or AAAA record (IPv6) with a TTL. Modern browsers also ask for the HTTPS record, which can say “this site supports HTTP/3”. See DNS. - Connection. With both IPv4 and IPv6 answers the browser races them (Happy Eyeballs) and keeps the first that connects.
- TCP: the three-way handshake, SYN, SYN-ACK, ACK. One round trip.
- QUIC: if the browser knows the site speaks HTTP/3, it sends a UDP packet to port 443 that carries the transport and TLS handshakes together.
- TLS handshake. In TLS 1.3 this takes one round trip. The client sends ClientHello with the server name (SNI), the protocols it speaks (ALPN:
h2,http/1.1) and a key share. The server answers with its key share, its certificate and a signature. The browser checks the certificate chain up to a root it trusts, the name, the dates and the signature. Both sides now have the same session keys. See TLS. - HTTP request. The browser sends
GET /with headers such asHost,User-Agent,Accept-EncodingandCookie. On HTTP/2 and HTTP/3 this is a binary frame on a stream, and many requests share one connection. See HTTP versions. - The server side. The IP usually belongs to a CDN or a load balancer, not the application. A typical chain is CDN edge, load balancer, reverse proxy or ingress, application, database. TLS is often terminated at the edge and started again towards the origin.
- HTTP response. A status code (
200,301,404,503), headers (Content-Type,Cache-Control,Set-Cookie,Content-Encoding: br) and the body. - Rendering. The browser parses HTML into the DOM and CSS into the CSSOM, combines them into a render tree, computes layout, paints and composites. CSS blocks rendering. A plain
<script>blocks parsing until it has downloaded and run;deferandasyncavoid that. - Subresources. Every stylesheet, script, image and font repeats steps 3 to 9, mostly over the connection that is already open. Other origins need their own DNS lookup and connection.
How many round trips before the first byte of the request
Section titled “How many round trips before the first byte of the request”| Setup | Round trips before the request | Notes |
|---|---|---|
| TCP + TLS 1.2 | 3 | 1 TCP, 2 TLS |
| TCP + TLS 1.3 | 2 | 1 TCP, 1 TLS |
| QUIC (HTTP/3), first visit | 1 | transport and TLS handshake combined |
| TLS 1.3 or QUIC resumption with 0-RTT | 0 extra for the request | early data can be replayed, so only safe for idempotent requests |
DNS adds its own round trip on a cold cache, in every row.
Compare
Section titled “Compare”Where time goes, and what fixes it.
| Stage | Typical cost | What reduces it |
|---|---|---|
| DNS | 1 to 100+ ms cold, 0 cached | longer TTLs, a nearby resolver, dns-prefetch |
| TCP handshake | 1 round trip | keep-alive, connection reuse, HTTP/3 |
| TLS handshake | 1 round trip (1.3) | session resumption, 0-RTT, TLS termination close to the user |
| Request and server time | application-dependent | caching, CDN, faster back end |
| Download | size divided by bandwidth | compression (Brotli, zstd), smaller assets, CDN |
| Render | CPU-dependent | less blocking CSS and JavaScript, defer, lazy loading |
Who answers on port 443, from the outside in.
| Hop | Job | Examples |
|---|---|---|
| CDN edge | cache, TLS termination, DDoS and WAF filtering | Cloudflare, CloudFront, Fastly |
| Load balancer | spread connections across healthy targets | AWS ALB and NLB, Google Cloud Load Balancing, HAProxy |
| Reverse proxy or ingress | routing by host and path, retries, rate limits | nginx, Envoy, Traefik, Kubernetes Ingress or Gateway |
| Application | business logic | your service |
| Data stores | state | PostgreSQL, Redis, object storage |
What breaks
Section titled “What breaks”Work from the bottom layer up. Each command answers one question.
| Symptom | Likely layer | Check |
|---|---|---|
DNS_PROBE_FINISHED_NXDOMAIN, “could not resolve host” |
DNS | dig +short example.com, dig @1.1.1.1 example.com, dig +trace example.com |
| Hangs, then “connection timed out” | network or firewall drops packets | nc -vz example.com 443, mtr example.com, security groups |
| “Connection refused” straight away | nothing listens on that port | ss -ltnp on the server, target health on the load balancer |
| Certificate error | TLS: expired, wrong name, missing intermediate | openssl s_client -connect example.com:443 -servername example.com |
502 Bad Gateway |
the proxy reached the back end and got a bad or no answer | proxy logs, back end crashed or closed the connection |
503 Service Unavailable |
no healthy back end | health checks, pod readiness |
504 Gateway Timeout |
the back end did not answer in time | back end latency, proxy timeout settings |
| Slow first load only | cold DNS, cold connection, cold cache | timing breakdown below |
One command that times every stage:
curl -s -o /dev/null -w 'dns %{time_namelookup}\ntcp %{time_connect}\ntls %{time_appconnect}\nttfb %{time_starttransfer}\ntotal %{time_total}\n' https://example.com/Each value is cumulative seconds from the start, so the TLS handshake took time_appconnect - time_connect.
See which HTTP version was negotiated and all response headers:
curl -sI --http3 https://example.com/ # needs a curl built with HTTP/3curl -sIv https://example.com/ 2>&1 | grep -E 'ALPN|HTTP/'Keywords
Section titled “Keywords”URL, HSTS, HSTS preload, DNS, recursive resolver, authoritative server, A record, AAAA record, HTTPS record, TTL, Happy Eyeballs, TCP three-way handshake, SYN, ACK, QUIC, UDP 443, TLS 1.3, ClientHello, SNI, ALPN, certificate chain, session resumption, 0-RTT, HTTP/2, HTTP/3, CDN, load balancer, reverse proxy, TLS termination, status code, Cache-Control, DOM, CSSOM, render-blocking, TTFB, round trip time (RTT).
Sources
Section titled “Sources”- RFC 9110: HTTP Semantics
- RFC 9846: TLS 1.3 (July 2026, replaces RFC 8446)
- RFC 9000: QUIC
- RFC 9114: HTTP/3
- RFC 1034: Domain names, concepts and facilities
- RFC 8305: Happy Eyeballs version 2
- RFC 9460: SVCB and HTTPS DNS records
- RFC 6797: HTTP Strict Transport Security
- MDN: How browsers work
- curl: write-out variables