Contents

What DNS Actually Does When You Type a URL

The lookup chain that runs before a single byte of your page arrives

Contents

Type a web address into a browser and, before a single byte of the actual page arrives, a small chain of questions gets asked and answered across several different servers, most of them nowhere near you and nowhere near the site you’re visiting. That chain is DNS, and it runs so quickly and so invisibly that most people go their whole working life without ever seeing it happen. Once you watch it happen deliberately, a lot of “the internet is being slow” and “I can’t reach this site” complaints stop being mysterious.

The Problem DNS Actually Solves

Advertisement

Computers address each other by number — an IP address — not by name. Nobody wants to memorise a string of digits for every site they visit, so DNS exists to do one job: translate the name a human types into the number a computer needs, on demand, for essentially every domain in existence. It’s a directory service, structurally closer to a phone book than to anything resembling the web page it’s about to help you reach. The web page itself doesn’t move through DNS at all; DNS’s entire contribution is handing back an address, after which an entirely separate connection carries the actual content.

That separation matters because it explains why DNS problems and web server problems look identical from the outside — “the site won’t load” — while being fixed in completely different places. If DNS can’t resolve the name, your browser never learns which server to even ask for the page. If DNS resolves fine but the web server is down, you get a different failure, later in the process, after the name has already been turned into an address successfully.

The Chain, in the Order It Actually Happens

The first place your computer checks is its own local cache — records of names it has already looked up recently, kept for as long as each record’s time-to-live allows, so it doesn’t have to repeat work it did moments ago. If the name isn’t cached, the query goes to a resolver, typically one configured by your operating system or router, often provided by your ISP or a public option you’ve chosen yourself. This resolver does the actual legwork of finding the answer if it doesn’t already have it cached from a previous request made by someone else on the same resolver.

If the resolver doesn’t have the answer cached either, it starts at the top of a hierarchy and works down. It first asks one of the internet’s root servers for a pointer rather than a finished answer: “who’s responsible for the .com (or .org, .rs, whichever) part of this name?” The root server doesn’t know where vo.rs lives; it only knows which servers handle the .rs top-level domain, and it hands back that referral. The resolver then asks one of those top-level domain servers the same kind of question, one level more specific: “who’s responsible for vo.rs itself?” That server responds with the actual authoritative name servers for vo.rs — the servers that hold the real, current records for that domain. Finally, the resolver asks one of those authoritative servers directly for the record it originally wanted, and this time gets a real answer: an IP address, handed back down the chain to your computer.

1
2
3
4
5
6
$ dig +trace example.com

.                      86400  IN  NS  a.root-servers.net.
com.                   172800 IN  NS  a.gtld-servers.net.
example.com.           86400  IN  NS  a.iana-servers.net.
example.com.           86400  IN  A   93.184.216.34

Each step in that trace is a separate query to a separate server, each one narrowing the referral until the final authoritative answer comes back. In ordinary browsing this entire chain happens in the background, frequently in well under a hundred milliseconds, and the vast majority of it is skipped entirely because caches — at your resolver, and sometimes at your own machine — already hold the answer from a previous lookup by you or someone else nearby.

Why the Root Servers Don’t Buckle

Advertisement

It’s reasonable to wonder how thirteen-ish root server addresses handle lookup traffic from the entire planet without collapsing. The answer is that each of those addresses is an anycast address, announced from many physically distinct locations around the world, and ordinary internet routing sends your query to whichever announcing location is topologically nearest to you at that moment. You’re very likely never actually reaching a server in the country most associated with that root letter; you’re reaching a local copy that happens to answer to the same address. This is also why root and top-level domain lookups feel instant even though the servers are, in principle, a long way from most of the people asking them anything.

Recursive Resolvers Versus Authoritative Servers

It’s worth being precise about a distinction the trace above glosses over. The resolver doing all the asking — checking its cache, then querying root, then top-level domain, then the domain’s own name servers — is called a recursive resolver, and its whole job is to do that multi-step legwork on your behalf so your computer only has to ask one question and wait for one answer. The servers being asked at each step — root, top-level domain, and the domain’s own name servers — are authoritative for their particular slice of the hierarchy: each one is the single correct source of truth for that layer, and none of them do any recursion themselves. A root server never goes off and queries a top-level domain server for you; it simply tells your recursive resolver where to ask next, and leaves the recursion to that resolver.

This distinction is why running your own resolver at home is a genuinely different thing from running your own authoritative name server. A home resolver, such as Unbound or a Pi-hole’s built-in resolver, does the recursive legwork itself instead of forwarding it to an ISP’s resolver, which mostly buys you privacy — your queries stop being visible to a third party — and local control, like blocking known ad and tracker domains before they’re ever resolved. Running your own authoritative server is a different job entirely: it’s for publishing your own domain’s records to the rest of the world, and almost nobody needs to self-host that part when a registrar or DNS provider will do it reliably for a domain you don’t operate at any real scale.

Why Caching Makes This Fast, and Occasionally Wrong

Every DNS record is published with a time-to-live, a number of seconds telling any resolver how long it’s allowed to keep using its cached copy before it must ask again. Short TTLs mean changes propagate quickly but every resolver has to repeat the lookup more often; long TTLs mean less repeated lookup traffic but slower propagation when a record actually changes. This is why moving a website to a new server and updating its DNS record doesn’t take effect for everyone instantly — some visitors are still being served an address from a resolver that cached the old record and hasn’t hit its expiry yet.

It’s also why “clear your DNS cache” is genuine, useful advice rather than superstition when a site has moved and you’re still landing on the old server. Your own machine keeps a local cache in addition to whatever your configured resolver caches, and flushing the local one forces a fresh lookup rather than reusing a stale answer that’s technically still within its advertised lifetime on your end.

Who Gets to See What You Looked Up

Every one of those queries, in the classic setup, travels across the network in plain text, which means anyone able to observe traffic between you and your resolver — an ISP, a network operator, anyone sharing an unencrypted network with you — can see every domain name you look up, even for connections that are otherwise encrypted end to end once they’re established. The lookup happens before the encrypted connection exists, and historically it happened in the open. DNS-over-HTTPS and DNS-over-TLS exist specifically to close this gap, wrapping the same query-and-answer exchange described above inside an encrypted channel so an observer sees that a DNS query happened, but not which name was being asked about.

This is a genuine privacy improvement, and also a genuine headache for anyone running local DNS-based filtering, because a browser or app that decides to send its DNS-over-HTTPS queries straight to a public provider can quietly bypass a household ad-blocking resolver entirely, without asking. Getting encrypted DNS and local filtering to coexist deliberately, rather than having one silently defeat the other, is one of the more common self-hosting headaches once you start caring about both at once.

What Actually Gets Asked For

A lookup for a plain domain typically wants an A record (the IPv4 address) or an AAAA record (the IPv6 address), but DNS carries several other record types doing distinct jobs. An MX record says which mail servers handle email for a domain — a completely separate lookup from the one your browser makes, which is why a website and its email can be hosted on entirely different infrastructure without either one knowing about the other. A CNAME record is an alias, pointing one name at another name to be looked up in turn rather than at a raw address directly — useful when a service you don’t control hosts your subdomain and its own address might change. A TXT record holds arbitrary text, commonly used today for domain verification and for email authentication schemes that let a receiving mail server check whether a message claiming to come from your domain was actually allowed to.

Troubleshooting: Reading the Chain Yourself

Most DNS problems reveal themselves quickly once you stop guessing and start asking the same questions the resolver asks, directly.

If a site won’t load, check whether the name resolves at all before assuming the site itself is down:

1
2
$ dig example.com +short
93.184.216.34

No output at all usually means the resolver couldn’t find any record, which points at either a genuinely broken domain or a resolver-side problem rather than the destination server.

If a change you made — moving a site, updating a record — doesn’t seem to have taken effect, check the record’s TTL and compare it against how long ago you made the change:

1
2
3
$ dig example.com
;; ANSWER SECTION:
example.com.    3600    IN  A   93.184.216.34

A 3600 there means an hour, and any resolver that cached the old value within that window will keep serving it until the hour’s up on its end, regardless of when you actually changed it.

If one device on your network resolves a name fine and another doesn’t, compare which resolver each one is actually using — it’s easy to assume both are hitting the same upstream when in practice one is using a router-provided resolver and another has a manually configured public one, and only one of those has the record cached, or blocked, or otherwise different from the other.

If a name resolves to the wrong address entirely, and you’re on a network with local DNS overrides — a Pi-hole, a router doing ad-blocking, or a self-hosted resolver with custom entries — check those overrides before assuming the domain’s real, public record is broken. A local resolver returning its own answer for a name, correctly, is one of the most common causes of “this looks wrong” that isn’t actually a DNS fault at all.

Is It Worth Understanding the Chain?

For most people, no — DNS is deliberately built to be invisible, and it succeeds at that job the overwhelming majority of the time. But the moment something in your setup touches names — a self-hosted service, a domain you manage yourself, a network with its own resolver — understanding the actual chain turns a vague “the internet is broken” into a specific, checkable question: is this a caching issue, a resolver issue, or a genuine problem with the authoritative record. That’s the difference between guessing and diagnosing, and it’s a skill that pays for itself the first time a site migration goes sideways. If you’re running your own resolver at home, Pi-hole meets Unbound for network-wide ad blocking is a natural next step, and split-horizon DNS at home: one domain, two answers covers exactly the kind of “correct but confusing” local override case described above.

Advertisement
Advertisement
Smarc
Written by Smarc

Founder and editor of vo.rs. A lifelong tinkerer who self-hosts far more than is sensible, hardens Linux boxes for fun, and prods the latest AI tools to see what they can really do. The how-to guides here are the notes Smarc wishes had existed the first time round.