Table of contents
- Without a Name, Nobody Can Find You
- Domains Grow Like Trees
- From Domain Name to IP Address
- Recursive Query vs. Iterative Query
- Common DNS Record Types
- TTL and Caching — The Heart of DNS
- Reading dig Output
- DNS Security — Can You Trust It?
- Common DNS Issues in Practice
- Wrapping Up the Series So Far
Without a Name, Nobody Can Find You
In Part 2, we said computers find each other using IP addresses. But it’s impossible for a human to memorize 93.184.216.34 and type it in to visit a website. Machines use numbers; humans use names. The translator between the two is DNS (Domain Name System).
DNS is more than a simple “phone book that converts names to IPs.” It’s a massive, globally distributed hierarchical database that processes trillions of queries per second, and where latency is felt in milliseconds. If DNS hiccups for even a second, countless services become invisible simultaneously. That’s why DNS is also one of the most frequently scratched wounds in infrastructure operations.
In this post, we’ll look at what happens from the moment you type example.com in the browser until that name becomes an IP, how the division of labor works among name servers, and why caching and TTL are at the center of every DNS discussion.
Domains Grow Like Trees
DNS names follow a hierarchical structure separated by dots. The further right you go, the higher the level. Breaking down www.example.com:
. ← Root (usually omitted)
com ← TLD (Top-Level Domain)
example.com ← Second-level domain
www.example.com ← Subdomain
Strictly speaking, there’s one more dot at the very end (www.example.com.). This dot points to the root. It’s normally omitted, but you’ll encounter it occasionally when writing DNS configuration files. This tree structure is the starting point of DNS design.
flowchart TB
ROOT["."]
ROOT --> COM["com"]
ROOT --> KR["kr"]
ROOT --> ORG["org"]
COM --> EX["example.com"]
COM --> GOOG["google.com"]
KR --> COKR["co.kr"]
COKR --> NAV["naver.co.kr"]
EX --> WWW["www.example.com"]
EX --> API["api.example.com"]
Each level of this tree has its own dedicated name server. No single entity knows everything. Each one delegates to the level below by saying “go ask over there.” This delegation structure is what gives DNS its scalability.
From Domain Name to IP Address
Let’s trace step by step what DNS does from the moment you type www.example.com and press Enter until the connection begins.
sequenceDiagram
participant U as Browser
participant R as Resolver<br/>(ISP/Cloudflare)
participant Root as Root Name Server
participant TLD as .com TLD<br/>Name Server
participant Auth as example.com<br/>Authoritative Name Server
U->>R: A record for www.example.com?
Note over R: In cache? No.
R->>Root: www.example.com?
Root-->>R: Ask over there for .com (NS)
R->>TLD: www.example.com?
TLD-->>R: Ask over there for example.com (NS)
R->>Auth: www.example.com?
Auth-->>R: 93.184.216.34
R-->>U: 93.184.216.34
Note over U: TCP connection begins
Let’s unpack each step.
- Browser → OS resolver (Stub Resolver): The browser asks the OS to “please convert this name to an IP.” On Linux, this goes through a system call like
getaddrinfo() - OS → Recursive Resolver: The OS forwards the query to its configured resolver (usually the router, ISP, or a public resolver like
1.1.1.1or8.8.8.8). The recursive resolver does the actual legwork - Resolver → Root Name Server: The resolver asks the root “who manages
.com?” The root responds with the address of the.comTLD name server. There are actually 13 root server addresses (A through M) operated globally via anycast - Resolver → TLD Name Server: The resolver asks the
.comserver “who managesexample.com?” The answer is the address ofexample.com’s authoritative name server - Resolver → Authoritative Name Server: Now the resolver asks the server that manages
example.comdirectly: “What’s the A record forwww.example.com?” It receives the final answer (the IP) - Resolver → OS → Browser: The answer travels back in reverse, and the resolver caches the result. If the same query comes again, it answers immediately without going all the way to the root
This entire process typically completes within tens of milliseconds. With a cache hit, it’s under 1ms. Conversely, if the cache is empty and every step must be traversed, it can take hundreds of milliseconds.
Recursive Query vs. Iterative Query
DNS queries operate in two modes. Clarifying this distinction makes the sequence diagram above much more meaningful.
A recursive query says “find the final answer and give it to me.” This is what browsers and OSes send to the resolver. The resolver takes responsibility for tracking down the answer.
An iterative query says “tell me what you know, and I’ll chase down the rest.” This is what the resolver sends to root/TLD/authoritative servers. Each name server answers to the extent of its knowledge, and if it doesn’t know, it just says “try asking over there.”
flowchart LR
C["Client"] -->|recursive| R["Resolver"]
R -->|iterative| N1["Root"]
R -->|iterative| N2["TLD"]
R -->|iterative| N3["Authoritative"]
Why this split? If root name servers had to handle recursive queries from every client, the world would grind to a halt. Resolvers handle the recursion on behalf of clients, while upper-level name servers answer lightweight “delegation information” quickly. It’s a design for scalability and load distribution.
Common DNS Record Types
DNS stores more than just “name → IP.” It holds various kinds of information, each tagged with a record type. Here are the essential types.
| Type | Purpose | Example |
|---|---|---|
| A | Name → IPv4 address | example.com → 93.184.216.34 |
| AAAA | Name → IPv6 address | example.com → 2606:2800:220:1::e |
| CNAME | Name → another name (alias) | www.example.com → example.com |
| MX | Mail server designation | example.com → mail.example.com (priority 10) |
| TXT | Arbitrary text. SPF/DKIM/domain ownership proof | example.com → "v=spf1 include:_spf.google.com ~all" |
| NS | Authoritative name server for this domain | example.com → ns1.example.com |
| PTR | IP → name (reverse lookup) | 93.184.216.34 → example.com |
| SRV | Service/port designation | _xmpp._tcp.example.com |
| CAA | Certificate issuance authority for this domain | example.com → "letsencrypt.org" |
CNAME deserves special attention. It’s an alias saying “this name is actually that name.” For example, if www.example.com is set as a CNAME for example.com, a resolver looking up www.example.com will then look up example.com again to get the A record. This chain causes an extra lookup, and deeply nested CNAMEs add up in latency.
CNAME has a major constraint: you cannot have a CNAME alongside other records for the same name. Therefore, you can’t use a CNAME on a root domain (example.com) — because the root must have SOA and NS records. This is why AWS offers ALIAS and Cloudflare offers CNAME Flattening as proprietary extensions.
MX and TXT are tied to email. MX tells mail where to go, and TXT proves the legitimacy of the sending domain (SPF, DKIM, DMARC). If these three aren’t configured properly, outgoing mail lands in spam. For details, official guides like the Google Workspace admin guide are good resources.
TTL and Caching — The Heart of DNS
Every DNS record comes with a TTL (Time To Live). It’s a number in seconds indicating “how long this answer can be kept in cache.” A TTL of 300 means 5 minutes; 3600 means one hour.
example.com. 300 IN A 93.184.216.34
↑
TTL (seconds)
Caching is what makes DNS performant. Once a name has been looked up, the resolver answers on behalf of the authoritative server until the TTL expires. This caching is what allows root and TLD servers to handle the entire world’s traffic.
At the same time, TTL determines how quickly changes propagate. If you want to change an IP but the TTL is 86400 (one day), the old IP may persist for up to a day in the worst case. That’s why the operational technique is to lower the TTL to something short (60 seconds, 300 seconds) before migration, and restore it to a longer value after completion. Setting TTL thoughtlessly high slows down incident response.
flowchart LR
U1["Client A"] --> R["Resolver cache"]
U2["Client B"] --> R
U3["Client C"] --> R
R -- "Only on cache miss" --> AUTH["Authoritative name server"]
Not every layer respects TTL faithfully, though. Browsers have their own DNS cache, the OS has nscd/systemd-resolved caches, and public resolvers may override TTL with their own policies. The answer to “I lowered the TTL to 60 seconds but it’s still going to the old IP” is almost always some layer’s cache.
Reading dig Output
The most fundamental tool for DNS diagnostics is dig. If it’s installed, you can try it right away.
dig example.com
# Example output
# ; <<>> DiG 9.18.0 <<>> example.com
# ;; global options: +cmd
# ;; Got answer:
# ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12345
# ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
#
# ;; QUESTION SECTION:
# ;example.com. IN A
#
# ;; ANSWER SECTION:
# example.com. 300 IN A 93.184.216.34
#
# ;; Query time: 12 msec
# ;; SERVER: 1.1.1.1#53(1.1.1.1)
How to read each section.
- HEADER: Metadata about the query.
status: NOERRORmeans success.NXDOMAINmeans “no such name,” andSERVFAILmeans “the resolver couldn’t get an answer.” This is where the fork in the road is - flags:
qr(response),rd(recursion desired),ra(recursion available),aa(authoritative answer — the response came from an authoritative name server). To see theaaflag, you need to query the authoritative server directly - QUESTION SECTION: The exact question you asked
- ANSWER SECTION: The answer. Listed as name, TTL, class (IN=Internet), type, value
- Query time / SERVER: How long it took and which resolver answered
Useful options.
# Specific record type
dig example.com MX
dig example.com AAAA
dig example.com TXT
# Query a specific name server directly (bypass cache)
dig @8.8.8.8 example.com
# Trace from root to authoritative
dig +trace example.com
# Just the answer, briefly
dig +short example.com
dig +trace shows you exactly what the resolver does — stepping through root → TLD → authoritative server to find the answer. Running it once lets you see the “delegation process” described in this post with your own eyes.
Two other commonly used tools are nslookup and host. The output format differs slightly, but they do similar things. For production debugging, dig is overwhelmingly preferred for the amount of information it provides.
DNS Security — Can You Trust It?
DNS was originally an unencrypted protocol. Anyone in the middle can eavesdrop on queries and responses, and can even forge them. Defenses have been introduced incrementally.
- DNSSEC: Authoritative name servers attach digital signatures to responses. Resolvers verify these signatures to detect forgery. Complex to implement, so adoption is still low
- DoT (DNS over TLS): Encrypts DNS queries between the resolver and client with TLS. Uses port 853
- DoH (DNS over HTTPS): Same goal, over HTTPS. Leverages the fact that firewalls have difficulty blocking HTTPS. Backed by Cloudflare, Google, Firefox, and others
This topic goes beyond the scope of this series. For deeper exploration, Cloudflare Learning Center: DNS is a good starting point.
Common DNS Issues in Practice
DNS looks simple in principle, but the real-world pain points are numerous.
- Migrating a domain with a large TTL: You need to lower the TTL days in advance
- CNAME on root domains: As mentioned, you can’t use a CNAME on the root. To work around this, you need the cloud vendor’s ALIAS/Flattening feature
- Split-horizon DNS: A configuration that resolves the same domain to different IPs depending on whether the query comes from inside or outside the corporate network. Misconfigured, it leads to “it works inside the office but not from outside”
- Kubernetes CoreDNS: The DNS that resolves internal service names within a cluster. Names like
my-svc.my-ns.svc.cluster.localgo through this server. If CoreDNS goes down, the entire cluster experiences “DNS failure” - Negative caching:
NXDOMAINresponses are also cached. Right after adding a new name, the old “does not exist” answer may temporarily persist
The diagnostic sequence when DNS issues are suspected during operations generally goes like this: query the authoritative name server directly with dig to confirm the correct answer, check again with public resolvers (@8.8.8.8, @1.1.1.1), and finally suspect the OS/application cache. If you skip this order and poke around randomly, finding the root cause takes forever.
Wrapping Up the Series So Far
Part 1 drew a map of the layers with the OSI and TCP/IP models. Part 2 established the addressing system with IP and subnets. Part 3 examined the two personalities of the transport layer with TCP and UDP. This part dissected DNS, one of the first protocols an application encounters.
Weaving the four parts together, you can see a single picture from the moment https://example.com is typed into the browser until the server returns HTML. DNS converts the name to an IP, IP guides the route, TCP establishes the connection, TLS adds encryption, and HTTP carries the request. Once this flow becomes second nature, you’ll instinctively ask “which layer is blocked?” when facing a network issue.
Many topics remain untouched by this series: modern protocols like HTTP/2, HTTP/3, and QUIC; firewalls and NAT traversal; BGP and internet routing; load balancer design; and traffic flow in service meshes. With the fundamentals in place, you can move on to those topics.
In the next post, we dissect the most widely used application protocol that runs on top of all this — HTTP. We’ll cover the structure of requests and responses, the evolution from HTTP/2 through HTTP/3, and the background behind HTTPS becoming the default.

Loading comments...