What Happens When You Type a URL (The Full Journey)

Terminal showing dig resolving a domain and curl fetching HTTP response headers
Real command output from a test machine, not a mock-up.

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.

Ethernet cables plugged into a server rack

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-Security header, or the domain is on the browser’s built-in HSTS preload list, the browser rewrites http:// to https:// internally before sending anything. In Chrome’s DevTools you will see this as a 307 Internal Redirect that 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=3600 and 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.

  1. Browser host cache. Checked first, as above.
  2. The operating system resolver. The browser calls the OS (on Linux, getaddrinfo()). On Linux, /etc/nsswitch.conf decides the order; the usual line is hosts: files dns, meaning /etc/hosts is read before any DNS query. On Windows, the DNS Client service keeps a cache that is preloaded with entries from C:\Windows\System32\drivers\etc\hosts, and ipconfig /displaydns shows it.
  3. The local stub resolver. On Ubuntu and most systemd distributions, systemd-resolved listens on 127.0.0.53 with its own cache, and /etc/resolv.conf points at it. It forwards misses to the DNS servers you got from DHCP or configured by hand.
  4. 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.
  5. Root, TLD, authoritative. On a cache miss, the recursive resolver asks a root server which servers handle .uk, asks those which servers handle readthemanual.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-Match or If-Modified-Since when the browser has a stale cached copy, so the server can answer 304 Not Modified instead 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:

  1. Give the 30-second overview first (the short answer at the top of this article), so they know you can see the whole path.
  2. 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.
  3. Mention a command at each stage. dig +trace, openssl s_client, curl -v and curl -w show you have actually looked, rather than memorised a list.
  4. 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 -w timing command against ten sites you use daily. Compare the DNS, connect, TLS and TTFB figures and explain the differences.
  • Run dig +trace for a .co.uk, a .com and a .io domain 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

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.

Return to How the Internet Actually Works Series

Enjoyed this guide?

New articles on Linux, homelab, cloud, and automation every 2 days. No spam, unsubscribe anytime.

Scroll to Top