Host Talk / What actually happens when you type a URL

What actually happens when you type a URL

HOST TALK

14 min read · 2,987 words

You type a web address, press Enter, and a page shows up. It feels instant, which is a little unfair to everything that just happened. At least six separate systems cooperated, most of them run by organisations that have never spoken to each other. Here is the slow-motion version.

The reason to look at it is practical. When someone says "the site is slow" or "the site is down", they are describing the end of a long chain, and the fault could be at any link. A name that does not resolve, a server that is far away, a certificate that has lapsed, an application that takes a second to build the page and a script from a third party that never finishes all look the same from the outside. Each one has a different fix and a different person who can make it.

So this piece follows a single request from the keyboard to the screen, noting what each stage does, roughly how long it takes, and how to look at it yourself.

Browsercaches DNSname to IP ConnectTCP / QUIC TLScertificate Requestserver builds Render+ all assets Any stage can be skipped if a cache or an open connection already has the answer A "slow site" is a slow stage, not a slow everything
The stages of one page load, in the order they happen on a first visit.

First, the browser looks for a shortcut

Before it asks anyone anything, the browser reads what you typed. If it looks like an address, it splits it into a scheme (https), a host (www.example.com), an optional port, a path and a query. If it does not look like an address, the browser treats it as a search. That is why a typo in a domain sometimes lands you on a search results page instead of an error. Names with accented or non-Latin letters are converted to an ASCII form starting with xn--, which is what the rest of the system understands.

Next, it checks whether it already knows where this site lives. Browsers keep a short-lived memory of recent lookups, and so does your operating system. If you visited the site a minute ago, the answer is probably sitting right there and the whole next step is skipped. The browser may also already hold an open connection to that host, or know from an earlier visit that the site must always be loaded over HTTPS (a rule called HSTS, set by a response header the site sent before). In that case a typed http:// address is upgraded before any request leaves the machine.

If the page itself is in the browser's cache and still fresh, nothing goes over the network at all. The fastest request is the one that never happens, and that holds all the way down this article.

Step one: turning a name into a number

Computers do not route traffic by name. They need an IP address, something like 203.0.113.25 (or an IPv6 one like 2001:db8::25). The job of finding that number belongs to DNS, and your device hands it to a resolver, usually run by your internet provider, your router, or a public service such as Google or Cloudflare.

The resolver may already have the answer cached. If not, it starts at the top. It asks one of the root servers who handles .com. The root server does not know the address of your site, but it knows who runs the .com zone, so it points the resolver there. The .com servers do not know the address either, but they know which nameservers your domain uses. Those nameservers are the ones that hold the actual records, and one of them finally says: the address is 203.0.113.25.

That chain of referrals sounds long, and in a cold cache it is, but each hop usually takes a few milliseconds. Everything gets cached along the way for as long as the record's TTL allows, which is why the second visit is so much faster than the first.

Your deviceasks for the IP Resolvercaches answers 1. Root servers"ask the .com servers" 2. .com servers"ask the domain's nameservers" 3. Authoritative nameserver"203.0.113.25, TTL 300" Answer returns the same way, and sits in the cache until the TTL ends
On a cold cache the resolver works down from the root; on a warm one it answers from memory and none of this happens.

What a DNS answer contains

The records you meet most are an A record (name to IPv4 address), an AAAA record (name to IPv6 address) and a CNAME (this name is an alias for that one). Each carries a TTL, in seconds, which tells caches how long they may remember it. A host with both A and AAAA records gives the browser a choice, and modern browsers try both quickly and use whichever connects first.

example.com.        300  IN  A      203.0.113.25
example.com.        300  IN  AAAA   2001:db8::25
www.example.com.    300  IN  CNAME  example.com.

The TTL is the reason a DNS change is not instant. If you change an address while the old record had a TTL of 86400 seconds, resolvers that cached it a minute ago may keep serving the old answer for most of a day. The TTL planner and the DNS cheat sheet go into the planning side.

Step two: opening a connection

With an address in hand, the browser connects. For years that meant a TCP handshake: a quick back-and-forth that establishes both sides are listening. The browser sends a SYN, the server answers with SYN-ACK, and the browser confirms. That costs one round trip before anything useful can be said. Newer sites can use HTTP/3, which runs over a protocol called QUIC and folds some of that setup into fewer round trips. You will not notice which one is used, but on a bad mobile connection the difference can be real.

The browser learns about HTTP/3 from an earlier visit (the server advertises it in a response header) or from a DNS record. The first visit to a site therefore usually goes over HTTP/2 on TCP, and later visits may switch. If a network blocks UDP, which QUIC uses, the browser falls back to TCP without bothering you.

Where the server sits matters here more than anywhere. A round trip within one country is only a few milliseconds. Across an ocean it is closer to a hundred. Each setup step that needs a round trip pays that price, so a distant server with a connection that is set up three times feels clearly slower than a nearby one, even if the server is quick. That is the case for content delivery networks, which place copies of your files near the visitor.

Mobile networks add their own wrinkle. A phone on a weak signal may have a round trip of 150 ms or more, with random packet loss that forces retransmissions. Each of those delays is multiplied by the number of sequential steps in the load, which is why a page that feels fine on office wifi can crawl on a train. Testing with the browser's network throttling option, set to a slow mobile profile, is the quickest way to see what those visitors see.

The TLS negotiation

Immediately after, if the address starts with https, comes the TLS negotiation. The server shows its certificate, the browser checks that it matches the name you typed, that it has not expired, and that it was issued by an authority the browser trusts. Then both sides agree on temporary keys, and from that point everything between them is encrypted.

With TLS 1.3 this takes one more round trip; resumed connections can be faster still. The detailed version is in the Host Talk series, in the pieces on the handshake and on trust chains. For now the useful point is that a certificate problem stops the process here, before the browser has asked for a single page. That is why an expired certificate produces a full-screen warning and not a half-working site.

Step three: asking for the page

Now the browser finally sends an HTTP request, which is surprisingly short. It says roughly: I would like the page at this path on this host, here is what I can understand, and here are the cookies I have for this site. Written out, the start of one looks like this:

GET /blog/ HTTP/2
Host: www.example.com
Accept: text/html
Accept-Encoding: gzip, br
Cookie: session=abc123

The Host line (in HTTP/2 and 3, the equivalent :authority field) is how one server can run many sites. The reply starts with a status code and headers, followed by the body:

HTTP/2 200
content-type: text/html; charset=UTF-8
content-encoding: br
cache-control: max-age=300
server: nginx

The three-digit status code is the server's one-word summary: 200 means fine, 301 and 302 mean look somewhere else, 404 means not found, 500 means the server failed, 503 means it is too busy or down for a moment. The status code reference lists them all. A redirect sends the browser back to the start with a new address, which adds another full round of work, so long redirect chains slow a site down for no gain.

Redirects: www, HTTPS and the extra round

Most sites answer on more than one address. The bare domain and the www form are separate names in DNS, and the site can be reached over plain HTTP as well as HTTPS. A tidy setup picks one canonical form and sends the others to it with a 301 (permanent) redirect. The cost is that a visitor who types example.com may go through two hops before they see anything: from HTTP to HTTPS, then from the bare name to www. Each hop is a full request and response, and on a new connection it may include another DNS lookup and TLS setup.

curl -sIL http://example.com/ | grep -iE '^(HTTP|location)'
HTTP/1.1 301 Moved Permanently
location: https://example.com/
HTTP/2 301
location: https://www.example.com/
HTTP/2 200

Two hops is acceptable; five is a smell. The usual cure is to make the first redirect go straight to the final address, so HTTP to HTTPS and bare to www happen in a single step. Redirect loops, where each rule undoes the other, give the browser's "too many redirects" error and are almost always an HTTPS rule in the web server fighting with a similar setting in the application or a CDN.

What the server does with it

On the server, a web program such as Apache or Nginx receives that. It first decides which site the request is for, using the host name, then which file or program should answer, using the path. If the page is a plain file, it just sends it. If the page is built dynamically, as on a WordPress site, the web server hands the request to PHP, PHP loads the site's code, asks the database for the post and the settings, assembles the HTML, and sends it back. That is the slowest part of most pages, and it is the reason caching exists.

A page cache stores the finished HTML for anonymous visitors, so the next request skips PHP and the database altogether. An object cache keeps the results of repeated database queries in memory. An opcode cache keeps PHP's compiled code ready. Hosts typically turn some of these on for you, and each one removes a chunk of the server's work. The time between the request arriving and the first byte leaving is what speed tests call time to first byte, and the piece on TTFB shows how to split it up.

A fast reply from the server is the one stage you can usually improve most cheaply: switch on page caching, use a current PHP 8.x version, and remove plugins you do not use. Every other stage depends more on geography, third parties or the visitor's own connection.

Step four: everything else

The HTML that comes back is rarely the whole story. It references stylesheets, scripts, fonts and images, and the browser fetches those too, often in parallel, sometimes from entirely different servers. A typical page might involve fifty or eighty separate requests. Only when enough of them have arrived does the browser draw anything meaningful.

The browser reads the HTML from the top and starts fetching what it finds. Stylesheets and scripts in the head can block drawing: the browser will not paint until it has the styles, because it would otherwise show an unstyled flash. Images do not block the first paint but they move things around when they arrive unless their dimensions were declared. Third-party scripts for ads, analytics and chat widgets each need their own DNS lookup, connection and TLS setup, since they live on other hosts. That is how a page can be quick on the server and still sluggish on screen.

Why repeat visits are faster: browser caching

Every response can carry instructions about how long the browser may reuse it. A header such as cache-control: max-age=31536000 on a stylesheet or image says the file can be kept for a year without asking again, which is why versioned file names (style.4f2a9c.css) are common: change the name, and the browser fetches the new file. For things that might change, the browser can ask a cheaper question. It sends the file's version tag (an ETag) or last-changed time, and the server replies 304 Not Modified with no body if nothing has changed. That saves the transfer but still costs a round trip.

The result is that a repeat visit may need only a few fresh requests, with most of the fifty or eighty files coming straight off disk. It also explains a classic puzzle: you update a stylesheet and visitors still see the old design for hours. The old file was cached with a long lifetime, and nobody told the browser it changed. Setting short lifetimes on HTML and long ones on versioned assets avoids most of that.

Illustrative waterfall, times not to scale HTML style.css app.js hero.jpg font.woff2 chat-widget.js a large image The HTML must arrive first; everything after it can run in parallel
Each bar is one request; long bars near the end (a large image, a slow third-party script) often decide how long the page feels.

A worked example with numbers

A small clothing shop complains that its home page takes about five seconds to appear for customers on phones. The owner's first guess is that the hosting is slow. Rather than guess, the support engineer loads the page in a fresh browser profile with the Network tab open and writes down what each stage cost. These figures are illustrative but typical of such a case:

StageTimeComment
DNS lookup40 msFine; nameservers respond quickly
Connection and TLS130 msNormal for a server in the same country
Waiting for the first byte1,100 msSlow; no page cache, so PHP and the database run every time
Downloading the HTML60 msFine
Images, scripts and fonts3,200 msHero image of 4 MB, three chat and tracking scripts

The server is not the main problem. A little over a second is spent waiting for the page to be built, which a page cache will cut to a fraction. But more than three seconds go on the rest, mostly on one oversized photograph and scripts from other companies. Resizing the image to a reasonable width and compressing it, and loading the chat widget only after the page has finished, takes the total below two seconds. The money spent on the plan would have changed almost nothing.

The habit worth keeping is to look for the longest bar before you form a theory. The same approach works for downtime reports: find the stage that failed first, then ask who owns it.

When a stage goes wrong

Every stage has its own signature. Once you can recognise them, a vague complaint becomes a specific question.

What you seeStageUsual cause
"Server not found" or DNS_PROBE_FINISHED_NXDOMAINDNSDomain expired, wrong nameservers, or a record never added
Site loads for some people, not others, after a moveDNSOld answer cached somewhere; TTL not yet expired
"Connection timed out" or refusedConnectionServer down, firewall blocking, wrong IP
Full-page certificate warningTLSExpired certificate, wrong name, missing intermediate
Too many redirectsRequestLoop between www/non-www, or HTTP/HTTPS rules
500 or 503 errorServerApplication error, or resource limit reached
Page appears, then jumps or crawlsRenderingHeavy images, blocking scripts, slow third parties

The troubleshooting guide has the longer version, with what to try for each.

Who owns each stage

One reason these problems drag on is that nobody can tell who to call. The stages belong to different parties, and knowing which is which saves a round of support emails.

StageWho runs itWho can fix it
Name registrationRegistrar and registryYou, at the registrar
DNS recordsYour DNS provider (often the host or registrar)You, in the DNS zone editor
Resolver cachingVisitor's provider or public resolverNobody; wait for the TTL
Server, web server, certificateYour host, or you on a VPSHost support or you
Application and pluginsYou or your developerYou or your developer
Third-party scriptsThe other companyYou, by removing or delaying them
Visitor's connection and deviceThe visitorMostly nobody; design for it

The row that matters most is the resolver caching one, because it is the only stage where the right action is to wait. Many "my change has not worked" tickets are just an old answer still sitting in a cache that nobody can empty on the visitor's behalf.

Commands worth running

Your browser's developer tools (F12, then the Network tab) show the waterfall in the figure above for any page. Tick "Disable cache" and reload to see a first-visit load. Click a request and open the Timing tab to see how long each stage took for that one resource.

From a terminal, dig shows the name lookup, and the +trace option shows the walk from the root:

dig www.example.com A +short
dig www.example.com +trace

For the connection and request, curl -v prints each stage, and the timing option gives numbers:

curl -sv https://www.example.com/ -o /dev/null 2>&1 | head -30
curl -so /dev/null -w 'dns %{time_namelookup} connect %{time_connect} tls %{time_appconnect} first-byte %{time_starttransfer} total %{time_total}\n' https://www.example.com/

Read the numbers as cumulative: the TLS figure includes the DNS and connection time before it. The difference between consecutive values is what each stage cost. Run it three times and ignore the first if it looks odd.

NextShared, VPS, dedicated and cloud: what actually differs

More from Host Talk

Host Talk

What a web server actually does

A web server is a program that waits for requests and answers them. The two names you will meet most are...

Host Talk

Shared, VPS, dedicated and cloud: what actually differs

Hosting plans are named in a way that suggests a ladder, with shared at the bottom and dedicated at the top....

Host Talk

PHP-FPM, and why your pages wait in line

Most WordPress sites run on PHP, and PHP does not run inside the web server any more. Modern setups use...