# How DNS Really Works

You've typed a URL into a browser more times than you can count. You've also, at some point, been the engineer paged because "DNS is broken", and if you're honest, you probably fixed it without fully understanding why it broke in the first place. Flushed a cache, waited it out, restarted something, moved on. DNS has a habit of being the thing everyone touches daily and almost nobody actually understands.

So let's actually walk through it. Not the one-line "it translates domain names to IP addresses" version, but the whole referral chain, the caching layers, and the part where a dozen different organisations across the planet cooperate to answer a question that none of them individually knows the answer to.

## **The tree nobody drew you**

DNS is organised as a tree, and every node in that tree owns a slice of authority. The root sits at the top. Below it are the top-level domains (TLDs): `.com`, `.io`, and the two-letter country codes like `.uk` or `.de`, known as ccTLDs. Below those are second-level domains (SLDs), and so on, until you hit the node that actually knows the IP address you're after.

Every domain name is just a path through that tree, written backwards and separated by dots. `example.com` means "the example node, under the com node, under the root." The root itself technically has a name too: an empty label, represented by a trailing dot. A fully qualified domain name (FQDN) makes that explicit, with a trailing dot added: `example.com` You'll almost never type it yourself; the resolution process handles it for you.

Each node delegates authority to its children and takes on a responsibility in return: making sure everything below it is uniquely named. `.com` has to guarantee `example` is unique within `.com`. It doesn't care what happens under `.io`. Whoever holds a zone, meaning the collection of records under a given domain, has to run at least two servers hosting that zone's data, called authoritative name servers, purely for redundancy. The root zone itself runs on 13 servers (`a.root-servers.net` through `m.root-servers.net`).

![](https://cdn.hashnode.com/uploads/covers/698ce732e249cba68b3bbdb5/93b3031c-3d86-4cdd-9d44-da499278df40.png align="center")

## **Chasing the referral chain**

Here's the part that trips people up: querying DNS isn't really "asking a database". It's chasing a chain of referrals until someone actually knows the answer.

Your machine runs something called a stub resolver, a lightweight client that's the first stop for any lookup. Before it even leaves your machine, it checks two local sources: your `/etc/hosts` file for manual overrides, and its own small cache. If neither has an answer, the stub resolver fires off a recursive query to a resolver, usually your ISP's, or a public one like Cloudflare's `1.1.1.1`. "Recursive" here means the stub resolver is handing off responsibility entirely: give me the full answer, I don't want to be involved in the legwork.

That's the resolver's problem now, and it earns its keep. If it doesn't have the answer cached, it starts walking the tree itself, iteratively this time, meaning it does the querying and follows referrals hop by hop. First stop, a root server, which has no idea what `example.com`'s IP address is, but knows exactly who to point towards: the `.com` TLD server. The TLD server doesn't know the IP either, but knows which authoritative name server holds `example.com`'s zone, and refers the resolver there. Finally, that authoritative server actually has the record and hands back the IP. For real this time, not another referral.

The resolver's pseudocode might look something like this:

```plaintext

find-ip(domain, server_ip):
  if(domain in cache):
    return cache[domain]
  resp = request(domain, server_ip) # sends network request which returns result or referral
  if(resp.referral == null):
    cache[domain] = resp.ip
    return resp.ip
  else:
    return find-ip(domain, resp.referral)

find-ip("example.com", root-nameserver-address)
```

*Note:* `find-ip` *calling itself is recursion in the everyday programming sense, a different thing entirely from the "recursive query" we just talked about. The protocol term describes the client's relationship to the resolver. Whether the resolver's own code loops or recurses internally is an implementation detail; what makes its queries to root, TLD, and authoritative servers iterative is that each of those servers only ever answers with what it currently knows and never chases anything further itself.*

To wrap this section up, here's a simple, everyday example:

> It's like trying to find someone's desk in a building you've never visited. You walk up to the ground-floor reception and ask for Dave from Example Corp. Reception has never heard of Dave, but they know Example Corp is on floor 12, so up you go. Floor 12's reception doesn't know Dave's desk number either, but points you to the right row. Only when you reach that row does someone actually know where Dave sits and can point straight at him. Nobody you spoke to along the way had the answer. They just knew who to send you to next.

That referral pattern is exactly why DNS scales to hundreds of millions of domains without collapsing under its own weight. Nobody has to hold the whole directory; they just have to know one level down.

## **Not all resolvers are equal**

It's worth being precise about the difference between a stub resolver and a recursive resolver, because conflating them is a genuinely common source of confusion when you're debugging.

The stub resolver lives on your machine and does almost nothing clever: check `/etc/hosts`, check a tiny local cache, forward the rest. The recursive resolver is the one doing real work, holding a much bigger cache, walking the tree, and absorbing the latency of slow lookups so your applications don't have to. Most people never choose their recursive resolver explicitly. It's whatever their ISP hands them via DHCP. Some of us do choose: Cloudflare's `1.1.1.1` is a common pick, mostly for speed and a genuinely audited privacy stance. They don't sell query data, and the bulk of what little they log is deleted within 25 hours. If you want the VPN-adjacent version of the same idea, their WARP client tunnels all your device's traffic over the same network. No affiliation, just deserves to be mentioned here.

If you ever want to see exactly what your browser thinks it knows, `chrome://net-internals/#dns` still works and shows Chrome's own resolver cache. Handy the next time you're trying to work out whether a stale record is a browser problem, an OS problem, or an actual DNS problem three hops away.

## **The TTL sticky note**

Every DNS record ships with a TTL, or time to live, telling resolvers how long they're allowed to cache the answer before asking again.

> Think of it like sticking a Post-it note with someone's phone number on your fridge. Next time you need to call them, you read the note instead of looking the number up again, much faster. But the note has an expiry date scrawled in the corner. Once that date passes, you throw it away and go look the number up properly, in case it changed.

This is also the single most common cause of "I changed the DNS record and nothing happened". Somewhere between you and the client, a resolver is still reading last week's Post-it note. It's why, if you're planning a change to an A record, the sane move is to drop the TTL well in advance, let the old value fully expire out of caches everywhere, make the change, and only then bump the TTL back up.

## **The record types you'll actually touch**

A quick reference, because you'll use maybe four of these regularly and forget the rest exist until you need them:

| **Record** | **What it does** |
| --- | --- |
| `A` | Domain to IPv4 address |
| `AAAA` | Domain to IPv6 address |
| `CNAME` | Alias to another name, never to an IP directly. Commonly used for subdomains |
| `MX` | Directs mail for the domain to a mail server, with a priority value for failover |
| `TXT` | Free-form text, these days mostly domain ownership verification and spam-prevention records |
| `NS` | Declares which server is authoritative for the domain |
| `SOA` | Zone metadata: admin contact, last-updated timestamp, refresh timings |
| `SRV` | Host and port for a specific service. Must point at an A/AAAA record, never a CNAME |
| `PTR` | Reverse lookup, IP to domain. Useful for spam filtering and for making sense of logs that only have an IP |

CNAME chains, where a CNAME points at another CNAME, technically work, but every extra hop is another lookup your client has to make before it gets an answer. Point straight at the A/AAAA record where you can.

## **Putting it all together**

![](https://cdn.hashnode.com/uploads/covers/698ce732e249cba68b3bbdb5/2386c66d-fa5c-4f33-802d-46b72ae647dd.png align="center")

## **Getting a domain live**

If you've never registered one yourself: you buy the name from a registrar, then a hosting provider (sometimes the same company, sometimes not) hosts the actual zone file on their name servers. The hosting provider's NS information gets registered against the TLD, which is what makes the domain queryable from anywhere on the internet. Once that propagates, you're live.

## **Why this actually matters**

Understanding the referral chain changes how you debug. "DNS is being weird" stops being a shrug and becomes a specific question: is this a stub resolver cache, a recursive resolver cache, a stale TTL, or an actually misconfigured record upstream? Each of those has a different fix, and only one of them is solved by "wait and see".

It also changes how you plan changes. Reduce your TTL before you touch a record, not after. Understand that "propagation delay" isn't some mystical internet phenomenon. It's just caches around the world honouring TTLs you set weeks ago. Once you've internalised that DNS is fundamentally a tree of servers that mostly don't know the answer and just know who to ask next, a whole category of "why is this slow" and "why is this stale" questions stop being mysterious.

* * *

*This piece skips DNSSEC, EDNS Client Subnet, and the fact that most of these servers are anycast, meaning many physical machines answering as a single IP.*
