How DNS Works
Computers talk to each other using IP addresses (numeric labels like 93.184.216.34), but humans are bad at remembering numbers. The Domain Name System (DNS — the internet’s phone book) bridges that gap: it turns a name you can read, like example.com, into the IP address a machine needs. Almost every connection you make starts with a DNS lookup, so understanding it is the foundation for buying domains, configuring servers, and debugging “the site won’t load” problems.
What problem DNS solves
Imagine if every time you wanted to visit a website you had to type its IP address. Worse, those addresses change when a server moves to new hardware or a new hosting provider. DNS adds a layer of names on top of addresses so that:
- Humans use stable, memorable names (
devcraftly.com). - Operators can change the underlying IP whenever they want, and nobody has to learn a new number.
A domain name is the readable address (example.com). A nameserver is a server whose job is to answer DNS questions. A DNS record is one entry that maps a name to a value — for example, “this name points to that IP.”
The four players in a lookup
When your computer needs the IP for www.example.com, four kinds of servers cooperate:
| Player | What it does | Example |
|---|---|---|
| Resolver (recursive resolver) | The server that does the legwork for you. Your computer asks it one question and it goes and finds the answer. | 1.1.1.1, 8.8.8.8, or your ISP’s |
| Root nameserver | The top of the tree. Doesn’t know the answer but knows who handles each TLD. | The 13 root server clusters |
| TLD nameserver | Handles a top-level domain (TLD — the last part of a name, like .com or .org). Knows which nameserver is in charge of each domain under it. | The .com nameservers |
| Authoritative nameserver | The final source of truth for a specific domain. Holds the actual records. | ns1.example.com |
A DNS lookup, step by step
Here is what happens when you open www.example.com for the first time (nothing cached yet):
- Your computer asks the resolver. It sends one question: “What is the IP for
www.example.com?” Then it waits. - Resolver asks a root nameserver. The root doesn’t know the IP, but it replies: “I don’t know, but the
.comnameservers do — here they are.” - Resolver asks a
.comTLD nameserver. The TLD doesn’t know the IP either, but it replies: “example.comis handled byns1.example.com— here is its address.” - Resolver asks the authoritative nameserver. This server holds the real records and answers: “
www.example.comis93.184.216.34.” - Resolver hands the answer back to your computer, and your browser connects to that IP.
This is called recursive resolution: you ask once, and the resolver chases the chain down on your behalf. The whole round trip usually takes only a few milliseconds.
TTL and caching
If every visit triggered all four steps, DNS would be slow and the root servers would melt. The fix is caching (temporarily storing an answer so you don’t have to ask again).
Every DNS record carries a TTL (Time To Live — how many seconds the answer may be cached). When a resolver gets an answer with a TTL of 3600, it remembers it for one hour. During that hour, anyone who asks gets the cached answer instantly without bothering the root, TLD, or authoritative servers.
Your operating system caches too, and so does your browser. This is why a DNS change you make sometimes takes a while to “spread” — old answers are still cached around the world until their TTL expires. This delay is called propagation.
Gotcha: Before you move a site to a new server, lower the record’s TTL (for example to 300 seconds) a day in advance. Then the cutover propagates in minutes instead of hours. Raise it back afterward to cut DNS traffic.
When to use a low vs high TTL
| TTL setting | When to use it | Trade-off |
|---|---|---|
| Low (60–300s) | Right before a migration, or for records that change often (failover IPs). | More lookups, slightly more load and latency. |
| High (3600–86400s) | Stable records that rarely change (your main website). | Changes take longer to propagate. |
Inspecting DNS with dig
dig (Domain Information Groper) is the standard tool for querying DNS. On Ubuntu it lives in the dnsutils package:
sudo apt update
sudo apt install dnsutils
Run a basic lookup:
dig example.com
Output:
;; ANSWER SECTION:
example.com. 3600 IN A 93.184.216.34
;; Query time: 24 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
The A record maps the name to an IPv4 address. The 3600 is the TTL. The Query time shows how long it took.
Ask for a specific record type by naming it at the end:
dig example.com MX
Output:
;; ANSWER SECTION:
example.com. 3600 IN MX 10 mail.example.com.
To see the whole resolution chain (every server queried, from root down), use +trace:
dig +trace example.com
For a clean answer with no extra noise, use +short:
dig +short example.com
Output:
93.184.216.34
You can also query a specific resolver directly — handy for testing whether a change has propagated to a public resolver yet:
dig @1.1.1.1 example.com +short
Inspecting DNS with nslookup
nslookup is an older, simpler tool, also in dnsutils. It is widely available (including on Windows and macOS), so it is useful when dig isn’t installed:
nslookup example.com
Output:
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: example.com
Address: 93.184.216.34
“Non-authoritative answer” means the result came from a cache or resolver, not directly from the domain’s authoritative nameserver.
dig vs nslookup — when to use which
| Tool | Use it when | Notes |
|---|---|---|
dig | Debugging, scripting, seeing TTLs and the full chain. | More detailed; supports +trace and +short. |
nslookup | Quick checks, or when dig isn’t installed. | Simpler output; less detail. |
Common record types
| Record | Maps a name to | Example value |
|---|---|---|
A | An IPv4 address | 93.184.216.34 |
AAAA | An IPv6 address | 2606:2800:220:1:248:1893:25c8:1946 |
CNAME | Another name (an alias) | www → example.com |
MX | A mail server | 10 mail.example.com |
TXT | Arbitrary text (used for SPF, domain verification) | "v=spf1 ..." |
NS | The authoritative nameservers for the domain | ns1.example.com |
Best Practices
- Query a known-good public resolver (
dig @1.1.1.1 yourdomain.com) when debugging — it rules out a broken local cache. - Lower your TTL well before any planned migration, then raise it back once the cutover is verified.
- Flush your local cache after a change so your own machine sees it:
sudo systemd-resolve --flush-caches(orsudo resolvectl flush-cacheson newer Ubuntu). - Use
dig +tracewhen an answer looks wrong — it shows exactly which server in the chain is returning stale or bad data. - Prefer
A/AAAArecords for your apex (root) domain andCNAMEonly for subdomains, since a CNAME cannot legally sit at the apex on most DNS providers. - Remember that propagation delays are caching, not the change “failing” — wait for the old TTL to expire before assuming something is broken.