
The Short Answer
When you type a URL and press Enter, the browser works out whether you meant a web address or a search, upgrades it to HTTPS if it can, and checks its caches. It then resolves the hostname to an IP address through DNS (browser cache, operating system resolver and hosts file, then a recursive resolver that walks root, TLD and authoritative servers). It opens a connection, either TCP plus a TLS 1.3 handshake or a single QUIC handshake for HTTP/3, verifies the server’s certificate, and sends an HTTP request. The request usually lands on a CDN edge or reverse proxy, which answers from cache or passes it to the origin server. The response comes back with a status code, headers and HTML, and the browser parses that HTML into the DOM, fetches CSS, JavaScript and images, builds the render tree, lays out the page and paints it.
That paragraph is the answer an interviewer wants to hear in the first 30 seconds. The rest of this guide takes each stage in order, shows you a command that lets you watch it happen on your own machine, and lists what breaks at that stage and the error text you will see when it does.
If you interview for infrastructure, DevOps, networking or support roles, some version of “What happens when you type a URL into a browser and press Enter?” (or “…when you type google.com”) is one of the most common questions you will get. The depth of your answer tells the interviewer roughly where you sit. A junior mentions DNS and HTTP. A strong candidate names the protocols, the round trips and the places it fails. Knowing the full path also makes you faster at fixing real problems, because you know which layer to test first.
Career Context: This question, or variations of it, appears in interviews for Network Engineer, Systems Administrator, DevOps Engineer, SRE, Cloud Engineer and Platform Engineer roles. Every step below is also a troubleshooting point in production, which is why interviewers like it: it tests theory and diagnostic instinct at the same time.

The Journey at a Glance
Use this as a cheat sheet. Each row has its own section below.
| Stage | What happens | See it yourself | Typical failure |
|---|---|---|---|
| 1. Input and caches | URL or search? Scheme added, HSTS upgrade, HTTP cache checked | DevTools Network tab, chrome://net-internals/#hsts |
Stale cache, redirect loops |
| 2. DNS | Name to IP: browser cache, OS stub resolver, hosts file, recursive resolver, root, TLD, authoritative | dig +trace, resolvectl query, Resolve-DnsName |
NXDOMAIN, SERVFAIL, wrong IP from a stale record |
| 3. TCP | SYN, SYN-ACK, ACK to port 443 (one round trip) | nc -zv host 443, curl -w |
Connection refused, connection timed out |
| 4. TLS 1.3 | Key exchange, certificate check, encrypted session (one round trip) | openssl s_client, curl -v |
Expired cert, name mismatch, missing intermediate |
| 5. HTTP request | Method, path, headers sent over HTTP/2 or HTTP/3 | curl -v |
400, 401, 403 |
| 6. Routing | Packets cross ISPs via BGP-selected paths | mtr, traceroute |
Packet loss, high latency |
| 7. Edge / proxy | CDN or reverse proxy terminates TLS, caches or forwards | Response headers (cf-cache-status, age) |
502, 504 |
| 8. Server | Static file or application code plus database | curl -w time to first byte |
500, slow TTFB |
| 9. Response | Status code, headers, body | curl -I |
Wrong status, missing cache headers |
| 10. Rendering | DOM, CSSOM, render tree, layout, paint, composite | DevTools Performance panel | Render-blocking CSS/JS, layout shift |
Step 1: The Browser Interprets What You Typed and Checks Its Caches
Before anything touches the network, the browser decides what your input is. readthemanual.co.uk looks like a hostname, so it becomes a URL. how dns works has spaces and no dot, so it goes to your search engine. If you type a bare hostname without a scheme, Chrome (since version 90) and other current browsers try https:// first rather than http://.
Then come the caches:
- HSTS: If the site has previously sent a
Strict-Transport-Securityheader, or the domain is on the browser’s built-in HSTS preload list, the browser rewriteshttp://tohttps://internally before sending anything. In Chrome’s DevTools you will see this as a307 Internal Redirectthat never left your machine. The header is defined in RFC 6797; MDN’s HSTS page covers the directives. - HTTP cache: If a previous response said
Cache-Control: max-age=3600and it is still fresh, the browser can serve it without a request at all. DevTools shows “(memory cache)” or “(disk cache)” in the Size column. - Browser DNS cache: Browsers keep their own short-lived host cache on top of the operating system’s. In Chrome you can view and clear it at
chrome://net-internals/#dns; in Firefox,about:networking#dns. - Existing connections: If the browser already has an open HTTP/2 or HTTP/3 connection to that host, it reuses it and skips Steps 2 to 4 entirely. This is why the second page you load on a site is faster than the first.
You can watch HSTS from the command line. A site that sends the header looks like this (output captured 31 October 2026):
curl -sI https://github.com/ | grep -i strict-transport
strict-transport-security: max-age=31536000; includeSubdomains; preload
A site that redirects plain HTTP at the server, instead of relying on HSTS, answers an http:// request with a real 301:
curl -sI https://readthemanual.co.uk/ | head -5
HTTP/1.1 301 Moved Permanently
Date: Sat, 31 Oct 2026 08:21:20 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Location: https://readthemanual.co.uk/
The difference matters: with only a 301, that first unencrypted request still goes out over the network, where it can be intercepted. HSTS, and especially preloading, stops the browser sending it in the first place.
Step 2: DNS Resolution, in the Order It Actually Happens
The browser needs an IP address for the hostname. We covered DNS itself in detail in Part 2 of this series; here is the exact order of lookups on a typical machine, because “which cache answered?” is the question that solves most DNS mysteries.
- Browser host cache. Checked first, as above.
- The operating system resolver. The browser calls the OS (on Linux,
getaddrinfo()). On Linux,/etc/nsswitch.confdecides the order; the usual line ishosts: files dns, meaning/etc/hostsis read before any DNS query. On Windows, the DNS Client service keeps a cache that is preloaded with entries fromC:\Windows\System32\drivers\etc\hosts, andipconfig /displaydnsshows it. - The local stub resolver. On Ubuntu and most systemd distributions,
systemd-resolvedlistens on127.0.0.53with its own cache, and/etc/resolv.confpoints at it. It forwards misses to the DNS servers you got from DHCP or configured by hand. - The recursive resolver. Your router, your ISP, a Pi-hole, or a public resolver such as 1.1.1.1. If it has the answer cached (within the record’s TTL), it replies straight away.
- Root, TLD, authoritative. On a cache miss, the recursive resolver asks a root server which servers handle
.uk, asks those which servers handlereadthemanual.co.uk, and asks the domain’s authoritative servers for the A (IPv4) and AAAA (IPv6) records. The protocol is defined in RFC 1034.
One nuance worth knowing: if the browser has DNS over HTTPS switched on (Chrome’s “Use secure DNS”, Firefox’s DNS over HTTPS setting), it sends queries straight to its DoH provider and bypasses the OS stub resolver. That is a common reason dig and the browser disagree about what a name resolves to.
See which cache answered, on Linux with systemd-resolved:
resolvectl query readthemanual.co.uk
Output captured 31 October 2026 from a Linux test machine (your interface name and addresses will differ):
readthemanual.co.uk: 2606:4700:3031::ac43:cc7f -- link: ens18
2606:4700:3036::6815:3a94 -- link: ens18
172.67.204.127 -- link: ens18
104.21.58.148 -- link: ens18
-- Information acquired via protocol DNS in 1.8ms.
-- Data is authenticated: no; Data was acquired via local or encrypted transport: no
-- Data from: cache
“Data from: cache” tells you the stub resolver answered locally. Clear it with resolvectl flush-caches and the next query will say “network”. The resolvectl manual lists the other subcommands. On Windows, the equivalents are Resolve-DnsName readthemanual.co.uk in PowerShell and ipconfig /flushdns.
Watch the full delegation chain with dig +trace:
dig +trace +nodnssec -4 readthemanual.co.uk
Output captured 31 October 2026 (trimmed: the root and .uk server lists are shortened):
. 7074 IN NS a.root-servers.net.
. 7074 IN NS b.root-servers.net.
...
;; Received 239 bytes from 127.0.0.53#53(127.0.0.53) in 0 ms
uk. 172800 IN NS nsa.nic.uk.
uk. 172800 IN NS nsb.nic.uk.
...
;; Received 552 bytes from 199.7.91.13#53(d.root-servers.net) in 15 ms
readthemanual.co.uk. 172800 IN NS deb.ns.cloudflare.com.
readthemanual.co.uk. 172800 IN NS nero.ns.cloudflare.com.
;; Received 102 bytes from 156.154.101.3#53(nsb.nic.uk) in 10 ms
readthemanual.co.uk. 300 IN A 104.21.58.148
readthemanual.co.uk. 300 IN A 172.67.204.127
;; Received 80 bytes from 172.64.35.28#53(nero.ns.cloudflare.com) in 6 ms
Read it top to bottom: the local stub hands dig the list of root servers, a root server (d.root) refers it to the .uk servers run by Nominet, a .uk server refers it to Cloudflare’s nameservers for the domain, and Cloudflare’s authoritative server returns two A records with a 300-second TTL. Note that dig +trace does the iteration itself rather than asking your recursive resolver, so it shows you what the authoritative servers say right now, not what your resolver has cached. Use -4 if your machine has no IPv6 route, otherwise you will see “network unreachable” lines as dig tries IPv6 nameservers first.
The HTTPS record: DNS that tells the browser about HTTP/3 before it connects. Modern browsers can also ask for an HTTPS resource record (RFC 9460) alongside the A and AAAA records. It advertises which protocols the server speaks and can carry IP hints and Encrypted Client Hello keys:
dig +noall +answer readthemanual.co.uk HTTPS
readthemanual.co.uk. 153 IN HTTPS 1 . alpn="h3,h2" ipv4hint=104.21.58.148,172.67.204.127 ech=AEX+DQBB...AAA= ipv6hint=2606:4700:3031::ac43:cc7f,2606:4700:3036::6815:3a94
alpn="h3,h2" means the browser can go straight to HTTP/3 on the very first connection instead of waiting to discover it (Step 4b). The ech= value lets a browser that supports Encrypted Client Hello hide which hostname it is asking for from anyone watching the network.
Step 3: The TCP Handshake
With an IP address, the browser opens a connection to port 443. For HTTP/1.1 and HTTP/2 that means TCP (RFC 9293), which needs a three-way handshake before any data flows:
1. SYN: The client sends a segment with the SYN flag and its initial sequence number.
2. SYN-ACK: The server replies with its own sequence number and acknowledges the client’s.
3. ACK: The client acknowledges the server’s number. The connection is open, and the client can send its first data in the same flight as this ACK.
That costs one round trip. If the server is 10 ms away it adds about 10 ms; across the Atlantic it is closer to 70 to 80 ms. This is the main reason CDNs put servers near users: every round trip in Steps 3 and 4 is paid in distance.
IPv6 first, then IPv4 (Happy Eyeballs). When a name has both AAAA and A records, browsers and curl try IPv6 and IPv4 in a staggered race and use whichever connects first. The algorithm is Happy Eyeballs v2, RFC 8305. You can see it in curl -v on a machine with no IPv6 route:
* IPv6: 2606:4700:3031::ac43:cc7f, 2606:4700:3036::6815:3a94
* IPv4: 104.21.58.148, 172.67.204.127
* Trying [2606:4700:3031::ac43:cc7f]:443...
* Immediate connect fail for 2606:4700:3031::ac43:cc7f: Network is unreachable
* Trying [2606:4700:3036::6815:3a94]:443...
* Immediate connect fail for 2606:4700:3036::6815:3a94: Network is unreachable
* Trying 104.21.58.148:443...
When a handshake fails, the error tells you which way. Connection refused means the host answered with a TCP reset: it is reachable, but nothing is listening on that port. Connection timed out means nothing answered at all: a firewall dropped the SYN, the route is broken or the host is down. Test the port directly:
# Linux / macOS
nc -zv readthemanual.co.uk 443
# Windows PowerShell
Test-NetConnection readthemanual.co.uk -Port 443
Step 4: The TLS 1.3 Handshake
Almost every site now uses HTTPS, so a TLS handshake runs on top of the TCP connection. It agrees encryption keys and proves the server is who it claims to be. TLS 1.3 (RFC 8446) does this in one round trip, where TLS 1.2 needed two:
1. ClientHello: The browser sends the TLS versions and cipher suites it supports, the hostname it wants (the SNI extension, so one IP can serve many sites), the protocols it can speak via ALPN (h2, http/1.1) and, crucially, a key share: its half of a Diffie-Hellman key exchange, guessed in advance.
2. ServerHello and the rest of the server’s flight: The server picks a cipher suite, sends its own key share, and from that moment both sides can derive the session keys. Everything after ServerHello is already encrypted: the server’s certificate chain, a CertificateVerify signature proving it holds the private key, and its Finished message.
3. Client verifies and finishes: The browser checks the certificate chains to a trusted root CA, has not expired, and lists the hostname in its Subject Alternative Name. If any check fails, you get the full-page warning. If it passes, the client sends Finished and the HTTP request straight after.
The older explanation, “the browser encrypts a session key with the server’s public key”, describes RSA key exchange, which TLS 1.3 removed. In TLS 1.3 the certificate’s key is only used to sign the handshake; the session keys come from the ephemeral key exchange, which is what gives forward secrecy.
0-RTT, and its catch. If you have connected recently, the server will have sent a session ticket. On the next visit the browser can resume with that ticket and send “early data” (the HTTP request) in its very first flight, with zero extra round trips. RFC 8446 is explicit that early data is not forward secret and can be replayed by an attacker, so servers should only accept it for requests that are safe to repeat, such as a plain GET (see section 8, “0-RTT and Anti-Replay”). Mentioning the replay risk is a good way to show depth in an interview.
See the handshake summary:
echo | openssl s_client -connect readthemanual.co.uk:443 -servername readthemanual.co.uk -brief
Output captured 31 October 2026 with OpenSSL 3.5.3:
CONNECTION ESTABLISHED
Protocol version: TLSv1.3
Ciphersuite: TLS_AES_256_GCM_SHA384
Peer certificate: CN=readthemanual.co.uk
Hash used: SHA256
Signature type: ecdsa_secp256r1_sha256
Verification: OK
Negotiated TLS1.3 group: X25519MLKEM768
DONE
That last line is worth a second look. X25519MLKEM768 is a hybrid key exchange that combines classic X25519 with ML-KEM, a post-quantum algorithm. Recent OpenSSL, browsers and CDNs negotiate it by default, so if an interviewer asks what is changing in TLS, this is a current, concrete answer.
Check the certificate’s names and dates:
echo | openssl s_client -connect readthemanual.co.uk:443 -servername readthemanual.co.uk 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates -ext subjectAltName
subject=CN=readthemanual.co.uk
issuer=C=US, O=Google Trust Services, CN=WE1
notBefore=Oct 9 14:19:36 2026 GMT
notAfter=Jan 7 15:17:27 2027 GMT
X509v3 Subject Alternative Name:
DNS:readthemanual.co.uk, DNS:*.readthemanual.co.uk
Always pass -servername. Without SNI, a server that hosts many sites may hand you its default certificate, and you will chase a “wrong certificate” problem that does not exist. The flags are documented in the openssl s_client manual.
Step 4b: HTTP/2 over TCP, or HTTP/3 over QUIC
During the TLS handshake, ALPN settles which HTTP version to speak. In the curl -v capture below you will see ALPN: curl offers h2,http/1.1 followed by ALPN: server accepted h2.
- HTTP/2 (RFC 9113) multiplexes many requests as streams over one TCP connection with compressed headers. Its weakness is TCP itself: one lost packet holds up every stream on the connection until it is retransmitted (head-of-line blocking).
- HTTP/3 (RFC 9114) runs over QUIC (RFC 9000) on UDP port 443. QUIC builds TLS 1.3 into its own handshake, so transport and encryption are set up in one round trip instead of TCP’s one plus TLS’s one. Streams are independent, so a lost packet only stalls its own stream, and connections can survive your phone moving from Wi-Fi to mobile data because they are identified by connection IDs rather than IP and port.
How the browser finds out HTTP/3 is available. Two ways. The first is the HTTPS DNS record from Step 2 (alpn="h3,h2"). The second is the Alt-Svc response header (RFC 7838, MDN) on an HTTP/2 response:
alt-svc: h3=":443"; ma=86400
That tells the browser “HTTP/3 is available on UDP 443, remember it for 86,400 seconds”, so the next connection uses QUIC. If a corporate firewall blocks outbound UDP 443, the browser quietly falls back to HTTP/2 over TCP. Pages still load, which is why this can go unnoticed for months.
To test HTTP/3 from the command line you need a curl built with HTTP/3 support. Check with curl -V and look for HTTP3 in the Features line; if it is there, curl --http3 -sI https://readthemanual.co.uk/ will show HTTP/3 200. Many distribution builds of curl do not include it yet, in which case you get “the installed libcurl version does not support this”. In the browser, DevTools’ Network tab has a Protocol column (right-click the column headers to add it) that shows h2 or h3 per request.
Troubleshooting Tip: If a site works in one browser but not another, or on one machine but not another, compare the TLS layer first. Old clients may not support TLS 1.3 or a newer root CA, a wrong system clock makes valid certificates look expired, and TLS-inspecting corporate proxies swap in their own certificate. openssl s_client from both machines usually shows the difference in a minute.
Step 5: The HTTP Request
With a secure connection open, the browser sends the request. HTTP semantics (methods, status codes, headers) are defined once in RFC 9110 and carried by HTTP/1.1, HTTP/2 or HTTP/3. A request contains:
- Method and path:
GET /from-arpanet-to-your-router/. In HTTP/2 and HTTP/3 these travel as pseudo-headers (:method,:path,:scheme,:authority). - Host / :authority: which site you want, since one IP may serve hundreds.
- User-Agent, Accept, Accept-Language, Accept-Encoding (for example
gzip, br, zstd): what the client is and what it can handle. - Cookie: session tokens and preferences previously set by this site.
- Conditional headers:
If-None-MatchorIf-Modified-Sincewhen the browser has a stale cached copy, so the server can answer304 Not Modifiedinstead of resending the body.
See the whole exchange with curl -v:
curl -sv -o /dev/null https://readthemanual.co.uk/
Output captured 31 October 2026 with curl 8.14.1 (trimmed; lines starting * are curl’s commentary, > is what you sent, < is what came back):
* Trying 104.21.58.148:443...
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519MLKEM768 / id-ecPublicKey
* ALPN: server accepted h2
* Server certificate:
* subject: CN=readthemanual.co.uk
* subjectAltName: host "readthemanual.co.uk" matched cert's "readthemanual.co.uk"
* issuer: C=US; O=Google Trust Services; CN=WE1
* SSL certificate verify ok.
* using HTTP/2
> GET / HTTP/2
> Host: readthemanual.co.uk
> User-Agent: curl/8.14.1
> Accept: */*
>
< HTTP/2 200
< content-type: text/html; charset=UTF-8
< server: cloudflare
< cf-cache-status: DYNAMIC
< alt-svc: h3=":443"; ma=86400
Every message of the TLS 1.3 handshake from Step 4 is visible there in order: one flight out (Client hello), one flight back (Server hello through Finished), then the client’s Finished and the request.
Measure Every Stage at Once with curl -w
This is the single most useful command in this article. curl’s --write-out variables (curl manual, Everything curl: write-out) report how long each stage took:
curl -o /dev/null -s -w "dns: %{time_namelookup}s
connect: %{time_connect}s
tls: %{time_appconnect}s
ttfb: %{time_starttransfer}s
total: %{time_total}s
protocol: HTTP/%{http_version}
" https://readthemanual.co.uk/
Output captured 31 October 2026 (from a UK connection with the DNS answer already cached):
dns: 0.000802s
connect: 0.004208s
tls: 0.018614s
ttfb: 0.051846s
total: 0.058790s
protocol: HTTP/2
Each value is cumulative from the start, so subtract to get the cost of each stage:
- DNS: 0.8 ms (served from the local cache).
- TCP: connect minus dns = about 3.4 ms, roughly one round trip to the nearest CDN edge.
- TLS: appconnect minus connect = about 14.4 ms.
- Server wait: ttfb minus appconnect = about 33 ms for the edge and origin to produce the first byte.
- Download: total minus ttfb = about 7 ms.
Now you can answer “the site is slow” with evidence. A large DNS figure points at the resolver. A large connect figure points at distance or packet loss. A large gap between appconnect and ttfb is the server or application. Run it a few times; the first run after a cache flush shows the true DNS cost.
Step 6: The Journey Through the Internet
Your request, encrypted inside TLS, inside TCP or QUIC, inside IP packets, crosses several networks. We covered routing in Part 1: each router forwards packets towards the destination based on its routing table, and between networks those paths are chosen by BGP.
For a UK user reaching a site behind a CDN, the path is usually short, because CDNs run edge servers in UK cities and peer directly with UK ISPs. For a site hosted in the US with no CDN, every round trip in Steps 3 and 4 crosses the Atlantic, which is why the same page can feel quick from one place and sluggish from another.
# Linux / macOS
traceroute readthemanual.co.uk
# Windows
tracert readthemanual.co.uk
# mtr combines traceroute with continuous ping: best for spotting loss
mtr -rwc 50 readthemanual.co.uk
When reading mtr, loss that appears at one hop and disappears at the next is usually that router rate-limiting replies to probes, not real loss. Loss that starts at a hop and continues all the way to the destination is the real thing.
Step 7: CDN Edge, Load Balancer or Reverse Proxy
Your request rarely reaches the application server directly. It usually lands first on a reverse proxy or load balancer, often operated by a CDN. It does several jobs:
- TLS termination: it holds the certificate and decrypts traffic, then talks to the backend over a separate connection (ideally also encrypted).
- Routing: based on the Host header and path, it sends the request to the right backend.
- Load balancing: round robin, least connections or weighted, with health checks to skip dead backends.
- Caching: it may answer from its own cache without contacting the origin.
- Security: rate limiting, WAF rules and DDoS absorption.
If you’ve followed our Nginx Proxy Manager guide, you’ve already built one of these. The same concept scales from a Raspberry Pi running Nginx to a CDN handling millions of requests per second.
For ReadTheManual, Cloudflare is the reverse proxy, which is why the dig output above returns Cloudflare addresses rather than the origin server’s. Response headers tell you what the edge did: in the capture above, server: cloudflare and cf-cache-status: DYNAMIC mean the edge passed the request to the origin rather than serving it from cache. HIT would mean the origin never saw the request. Other CDNs and proxies use headers such as x-cache or age for the same purpose.
Step 8: Server Processing
The request reaches the origin web server: Nginx, Apache, LiteSpeed, IIS, or an application server behind them. It does one of two things:
Static content: an HTML file, image or stylesheet is read from disk (or memory) and returned. Fast.
Dynamic content: the request is passed to application code. For WordPress, PHP runs the theme templates, queries MySQL or MariaDB for the post, assembles HTML and hands it back. A page cache in front of PHP can skip most of that work.
This is where slow database queries, exhausted PHP workers and slow calls to external APIs show up, and they show up as time to first byte. In the curl -w breakdown, a fast connect and TLS followed by a long wait before ttfb is the signature of a server-side problem.
Step 9: The HTTP Response
The response carries a status code, headers and a body. The status codes you will meet most:
| Code | Meaning | What It Actually Means |
|---|---|---|
| 200 | OK | Everything worked. Here’s your content. |
| 301 / 308 | Moved Permanently / Permanent Redirect | This URL has moved for good. 308 keeps the method (a POST stays a POST). |
| 302 / 307 | Found / Temporary Redirect | Go there for now, but keep using this URL. 307 keeps the method. |
| 304 | Not Modified | Your cached copy is still good. Use that. |
| 401 | Unauthorized | You haven’t authenticated (or your credentials were rejected). |
| 403 | Forbidden | The server knows who you are, or doesn’t care, and won’t allow it. |
| 404 | Not Found | That resource doesn’t exist. |
| 500 | Internal Server Error | Something broke in the application. Check the logs. |
| 502 | Bad Gateway | The proxy got an invalid response, or none, from the backend. Is the application running? |
| 503 | Service Unavailable | Overloaded or in maintenance. |
| 504 | Gateway Timeout | The backend took too long to respond. Slow query? Stuck process? |
Response headers include Content-Type, caching rules (Cache-Control, ETag), cookies to set (Set-Cookie), protocol hints (Alt-Svc) and security headers (Strict-Transport-Security, Content-Security-Policy). curl -I shows them on their own.
The body is the HTML, JSON or image bytes, usually compressed with gzip, Brotli or Zstandard depending on what the client offered in Accept-Encoding.
Step 10: Browser Rendering
The browser starts working on the HTML as soon as the first bytes arrive, not when the download finishes. MDN’s “How browsers work” walks through the same pipeline in more detail:
1. Parse HTML into the DOM. The parser builds the Document Object Model, a tree of every element. A preload scanner runs ahead of it, spotting stylesheets, scripts, fonts and images and starting their downloads early.
2. Fetch subresources. Each CSS file, script and image is another request. Same-host requests reuse the existing HTTP/2 or HTTP/3 connection; requests to other hosts (fonts, analytics, CDNs) go through DNS, TCP and TLS all over again.
3. Build the CSSOM. CSS is parsed into the CSS Object Model. CSS is render-blocking: the browser will not paint until it has the stylesheets in the <head>.
4. Run JavaScript. A plain <script> tag stops the HTML parser until it has downloaded and run. defer scripts run after parsing in order; async scripts run as soon as they arrive. Scripts can change the DOM and trigger more requests.
5. Style and layout. The DOM and CSSOM are combined into a render tree of visible elements, and layout calculates each element’s size and position for the current viewport.
6. Paint and composite. Elements are drawn into layers and the layers are composited onto the screen, often on the GPU. Later changes that alter size or position trigger layout again, which is what causes visible layout shift.
DevTools (F12) shows all of it. The Network tab shows each request with a timing breakdown (Queueing, DNS Lookup, Initial connection, SSL, Waiting for server response, Content Download), which maps directly onto Steps 2 to 9. The Performance panel shows parsing, scripting, layout and paint.
Practical Note: When a page takes four seconds instead of one, the server is usually not the main cause. Look first at the number of third-party hosts (each costs DNS, TCP and TLS), unoptimised images, render-blocking CSS and parser-blocking JavaScript. Start in the browser’s Network tab before you log in to the server.
Troubleshooting: Error Messages Mapped to the Layer That Failed
Most “the website is broken” tickets come with an error string. Each one points at a stage:
| Error you see | Layer | What it means and what to run |
|---|---|---|
DNS_PROBE_FINISHED_NXDOMAIN (Chrome), curl: (6) Could not resolve host |
DNS (Step 2) | The name does not exist, or the resolver could not get an answer. Check spelling, then dig name and dig @1.1.1.1 name to compare your resolver with a public one. status: SERVFAIL in dig often means a DNSSEC or authoritative server problem. |
| Site resolves to the wrong IP on one machine only | DNS caches / hosts file | Check /etc/hosts (or the Windows hosts file), then flush: resolvectl flush-caches, ipconfig /flushdns, and the browser’s own cache. |
ERR_CONNECTION_REFUSED, curl: (7) Failed to connect ... Connection refused |
TCP (Step 3) | Host reachable, nothing listening on the port. Is the service running and bound to the right address and port? ss -tlnp on the server. |
ERR_CONNECTION_TIMED_OUT, curl: (28) ... Connection timed out |
TCP / firewall | Packets are being dropped. Check firewalls and security groups, then the route with mtr. |
NET::ERR_CERT_DATE_INVALID |
TLS (Step 4) | Certificate expired, or the client’s clock is wrong. Check notAfter with openssl x509 -dates and the client’s time. |
NET::ERR_CERT_COMMON_NAME_INVALID |
TLS | The hostname is not in the certificate’s Subject Alternative Name. Check -ext subjectAltName, and make sure you passed -servername. |
curl: (60) SSL certificate problem: unable to get local issuer certificate |
TLS | The server is not sending its intermediate certificate, or the client’s CA bundle is out of date. openssl s_client -showcerts shows what the server sends. |
ERR_SSL_PROTOCOL_ERROR, ERR_SSL_VERSION_OR_CIPHER_MISMATCH |
TLS | No common TLS version or cipher, or something that is not TLS is answering on 443. Test with openssl s_client -tls1_2 and -tls1_3. |
ERR_TOO_MANY_REDIRECTS |
HTTP (Steps 7 to 9) | A redirect loop, classically a CDN talking HTTP to an origin that redirects everything to HTTPS. curl -sIL url prints each hop. |
| 502 Bad Gateway | Proxy to backend (Step 7) | Backend down or returning garbage. Check the proxy’s error log and whether the backend process is up. |
| 504 Gateway Timeout | Backend speed (Step 8) | Backend alive but too slow. Application logs, database slow query log. |
| Page loads but looks broken | Rendering (Step 10) | CSS or JS failed to load or was blocked. DevTools Console and Network tab, filter by failed requests. |
How to Answer This in an Interview
Interviewers are listening for structure, correct protocol names and the ability to go deeper on request. A good shape:
- Give the 30-second overview first (the short answer at the top of this article), so they know you can see the whole path.
- Offer to go deeper: “I can go into any of those in more detail. Is there a part you’re most interested in?” Many interviewers will steer you to DNS or TLS. Some want all of it.
- Mention a command at each stage.
dig +trace,openssl s_client,curl -vandcurl -wshow you have actually looked, rather than memorised a list. - Name a failure mode per stage. It shows operational instinct, which is what the question is really testing.
Follow-up questions to expect, with the short answers:
- “What if the DNS lookup fails?” NXDOMAIN versus SERVFAIL versus timeout, and how you would tell them apart with dig.
- “Why is TLS 1.3 faster than 1.2?” The client sends its key share in the first message, so the handshake takes one round trip instead of two. 0-RTT resumption removes it entirely for repeat visits, at the cost of replay risk.
- “What’s the difference between HTTP/2 and HTTP/3?” Same semantics; HTTP/3 runs over QUIC on UDP, combines the transport and TLS handshakes, and avoids TCP head-of-line blocking.
- “How does the browser know to use HTTP/3?” The Alt-Svc header on an earlier response, or an HTTPS DNS record with
alpn="h3". - “What does HSTS protect against?” SSL stripping on the first plain-HTTP request; preloading protects even the very first visit.
“What happens when you type a URL into a browser?” (The Full Answer)
“The browser first decides whether the input is a URL or a search, adds https if no scheme was given, and applies HSTS if the domain requires HTTPS. It checks its HTTP cache and whether it already has a connection open to that host. If it needs to resolve the name, it checks its own DNS cache, then asks the operating system, which checks the hosts file and the local stub resolver’s cache before querying the configured recursive resolver. On a miss, the recursive resolver walks from the root to the TLD to the domain’s authoritative servers and returns A and AAAA records, and possibly an HTTPS record advertising HTTP/3. The browser connects to port 443, racing IPv6 and IPv4. Over TCP that’s a SYN, SYN-ACK, ACK, then a TLS 1.3 handshake: ClientHello with a key share and SNI, the server’s reply with its certificate, and the browser verifies the chain, expiry and hostname. With HTTP/3 the QUIC handshake does transport and TLS together over UDP. ALPN settles on HTTP/2 or HTTP/3, and the browser sends a GET with Host, cookies and Accept headers. The request usually lands on a CDN edge or reverse proxy, which terminates TLS and either serves from cache or forwards to the origin, where the web server returns a static file or runs application code and database queries. The response comes back with a status code, headers and the HTML. The browser parses the HTML into the DOM, fetches CSS, JavaScript and images, builds the CSSOM, runs scripts, builds the render tree, does layout and paints.”
Adjust depth to the interviewer’s reaction. Some will stop you at TCP and move on; others will ask you to keep going into TLS key exchange or browser rendering. Either way, showing that you can go deep, and that you know how to observe each stage, is the point.
“A user says a website is showing a certificate error. How do you troubleshoot?”
“First I’d get the exact error, because ERR_CERT_DATE_INVALID, ERR_CERT_COMMON_NAME_INVALID and an untrusted issuer have different causes. Then I’d run openssl s_client -connect domain:443 -servername domain and pipe the certificate into openssl x509 -noout -subject -issuer -dates -ext subjectAltName. That shows whether it has expired, whether the hostname is in the SAN list, and who issued it. If the chain is incomplete, -showcerts shows whether the server is sending its intermediate. If it only happens for one user, I’d check their system clock and whether a corporate TLS-inspection proxy is replacing the certificate.”
“Explain the difference between a 502 and a 504 error.”
“Both come from a reverse proxy or load balancer reporting a problem with the backend. A 502 Bad Gateway means the proxy got an invalid response or none it could use: the backend is down, crashed, refused the connection or returned malformed data. A 504 Gateway Timeout means the proxy gave up waiting: the backend is alive but too slow, often stuck on a long database query or an external API call. For a 502, I check whether the backend process is running and reachable from the proxy. For a 504, I check what the backend is waiting on and what the proxy’s timeout is set to.”
Getting the nuance between 502 and 504 right is a detail that impresses interviewers. Many people treat them as interchangeable.
Career Application
On your CV (adapt to what you have actually done, with your own numbers):
- “Diagnosed web application incidents across DNS, TCP, TLS and application layers using dig, curl, openssl and mtr, reducing time to identify the failing layer”
- “Reduced page load time by [X]% through CDN caching, HTTP/2 and HTTP/3 enablement, and removal of render-blocking resources”
- “Configured and managed an Nginx reverse proxy handling TLS termination and load balancing for [N] backend services”
Build these debugging skills in your homelab:
- Run the
curl -wtiming command against ten sites you use daily. Compare the DNS, connect, TLS and TTFB figures and explain the differences. - Run
dig +tracefor a.co.uk, a.comand a.iodomain and note which organisation runs each TLD. - Set up Nginx Proxy Manager (our guide) and watch reverse proxying happen in its logs.
- Break things deliberately: put a wrong entry in your hosts file, serve an expired or self-signed certificate, stop a backend behind your proxy. Note the exact error at each layer, then fix it.
- Open DevTools (F12, Network tab) on a slow site, add the Protocol column, and see which requests are h2, which are h3, and which hosts cost a fresh DNS and TLS handshake.
Series Navigation
- Part 1: From ARPANET to Your Router — The physical internet and how data travels.
- Part 2: How DNS Actually Works — The system that turns names into numbers.
- Part 3: What Happens When You Type a URL — You are here.
- Part 4: The Birth of Cloud Computing — From MIT time-sharing to hyperscalers.
Every step in this chain is something you can observe, test, and debug from your own terminal. The tools are free. The knowledge is career-defining.
RTFM Apparel · printed in the UK

ReadTheManual is run, written and curated by Eric Lonsdale.
Eric has over 20 years of professional experience in IT infrastructure, cloud architecture, and cybersecurity, but started with PCs long before that.
He built his first machine from parts bought off tables at the local college campus, hoping they worked. He learned on BBC Micros and Atari units in the early 90s, and has built almost every PC he’s used between 1995 and now.
From helpdesk to infrastructure architect, Eric has worked across enterprise datacentres, Azure environments, and security operations. He’s managed teams, trained engineers, and spent two decades solving the problems this site teaches you to solve.
ReadTheManual exists because Eric believes the best way to learn IT is to build things, break things, and actually read the manual. Every guide on this site runs on infrastructure he owns and maintains.
Enjoyed this guide?
New articles on Linux, homelab, cloud, and automation every 2 days. No spam, unsubscribe anytime.






