How DNS Works: From Root Servers to an IP Address, Step by Step

DNS turns a name like larely.com into an IP address by asking a chain of servers: your resolver asks a root server where .com is handled, asks a .com server which name servers are responsible for larely.com, then asks one of those for the address. The answer is cached for as long as its TTL (time to live) allows, which is why DNS changes take time to appear everywhere.

You can follow every step yourself with nslookup, which ships with Windows and macOS, or dig on Linux and macOS. The outputs below are real, captured on 26 October 2026 from a Windows machine.

The four servers in a lookup

  1. Stub resolver: the small DNS client in your operating system. It forwards the question to a configured DNS server and waits for a final answer.
  2. Recursive resolver: usually your router, your ISP or a public DNS service. RFC 1034 describes recursive mode as the one where "the name server acts in the role of a resolver": it does all the follow-up queries on your behalf.
  3. Root and TLD servers: the root servers know which servers handle each top-level domain (.com, .org, .lt). The .com servers know which name servers handle each .com domain. Neither knows the final address; each returns a referral pointing one level further down.
  4. Authoritative name server: holds the actual records for the domain and gives the final answer.

The tree structure is the reason this scales. RFC 1034 notes that once an organisation controls its own zone, "it can unilaterally change the data in the zone" without asking anyone above it.

Step 1: ask a root server who handles .com

Adding a server name to nslookup sends the query straight to that server instead of to your resolver. a.root-servers.net is one of the root servers:

nslookup -type=NS com. a.root-servers.net

Output (trimmed and sorted):

Server:  UnKnown
Address:  198.41.0.4

com     nameserver = a.gtld-servers.net
com     nameserver = b.gtld-servers.net
com     nameserver = c.gtld-servers.net
...
com     nameserver = m.gtld-servers.net
a.gtld-servers.net      internet address = 192.5.6.30

The root server doesn't know anything about larely.com. It returns the 13 name servers for .com, plus their addresses so the next query can go straight to one.

Step 2: ask a .com server who handles larely.com

nslookup -type=NS larely.com a.gtld-servers.net
Server:  UnKnown
Address:  192.5.6.30

larely.com      nameserver = yolanda.ns.cloudflare.com
larely.com      nameserver = vern.ns.cloudflare.com
yolanda.ns.cloudflare.com       internet address = 173.245.58.241
vern.ns.cloudflare.com          internet address = 173.245.59.243

This is a delegation: the .com zone contains NS records saying that Cloudflare's name servers are authoritative for larely.com.

Step 3: ask the authoritative server for the address

-debug makes nslookup print the full response, including the TTL:

nslookup -debug -type=A larely.com yolanda.ns.cloudflare.com
    HEADER:
        opcode = QUERY, id = 2, rcode = NOERROR
        header flags:  response, auth. answer, want recursion
    QUESTIONS:
        larely.com, type = A, class = IN
    ANSWERS:
    ->  larely.com
        internet address = 172.67.188.63
        ttl = 300 (5 mins)
    ->  larely.com
        internet address = 104.21.48.227
        ttl = 300 (5 mins)

auth. answer confirms this came from an authoritative server. There are two A records, so clients can use either address. The ttl = 300 tells every resolver it may cache this answer for 300 seconds.

Your resolver does steps 1 to 3 the first time someone on your network asks, and then serves the answer from cache. With dig, dig +trace larely.com performs the whole chain in one command.

TTL and caching, measured

RFC 1034 defines the TTL as "a time limit on how long an RR can be kept in a cache." RFC 1035 specifies it in seconds. You can watch it count down by asking your normal resolver twice, 20 seconds apart:

nslookup -debug -type=A larely.com
first query:   internet address = 172.67.188.63   ttl = 32 (32 secs)
20 s later:    internet address = 172.67.188.63   ttl = 12 (12 secs)

The resolver had the record cached, and it reports how much of the 300 seconds is left. When it reaches zero, the resolver discards the record and asks the authoritative server again. Windows also keeps its own local cache; ipconfig /displaydns shows it, and the DNS cache flushing guide covers clearing it on each OS.

Why DNS changes "take time to propagate"

Nothing is pushed out when you change a record. The authoritative server starts giving the new answer immediately, but every resolver that cached the old answer keeps serving it until its TTL expires. "Propagation" is just thousands of caches expiring at different times.

  • A record with ttl = 300 is fully replaced within 5 minutes of the change.
  • A record with ttl = 86400 can be served stale for up to 24 hours.
  • Name server changes at the registrar depend on the TTL of the NS records in the parent zone (.com here), which you don't control.

To make a planned change fast, lower the record's TTL at least one old-TTL period in advance, make the change, then raise it again.

The record types you'll actually use

TypeHoldsReal example
AIPv4 address ("a host address", RFC 1035)larely.com → 172.67.188.63
AAAAIPv6 address (RFC 3596: "stores a single IPv6 address")larely.com → 2606:4700:3031::6815:30e3
CNAME"The canonical name for an alias": this name is another namewww.microsoft.com → www.microsoft.com-c-3.edgekey.net
MXMail server for the domain, with a preference number (lower is tried first)gmail.com → preference 5, gmail-smtp-in.l.google.com
TXTFree text, used for domain verification and email policies (SPF, DMARC)larely.com → "google-site-verification=…"
NS"An authoritative name server" for the zonelarely.com → vern.ns.cloudflare.com

Query any of them with nslookup -type=MX gmail.com (Windows/macOS) or dig MX gmail.com (Linux/macOS). A query for a name that has no records returns Non-existent domain (NXDOMAIN): www.larely.com currently returns exactly that, because no www record exists.

UDP, TCP and port 53

RFC 1035 assigns port 53 for DNS over both UDP and TCP and limits classic UDP messages to 512 bytes; longer answers are truncated with the TC bit set so the client retries over TCP. RFC 7766 later made TCP support mandatory: "All general-purpose DNS implementations MUST support both UDP and TCP transport." For the difference between the two transports, see TCP vs UDP.

If a lookup fails

  • Non-existent domain: the name has no records, or is misspelled. Ask the authoritative server directly to rule out a stale cache.
  • DNS request timed out: your resolver didn't answer in time. Try again, or query a different resolver to tell whether the problem is the resolver or the domain.
  • The answer is old: a cache is still holding it. Check the remaining TTL with -debug, flush your local cache, and wait out the rest.

Frequently asked questions

What is the difference between a recursive resolver and an authoritative server?
An authoritative server holds the records for a zone and answers only for that zone. A recursive resolver, usually run by your ISP, router or a public DNS service, does the legwork for clients: it asks the root, TLD and authoritative servers in turn, returns the final answer, and caches it for the record's TTL.
How long does DNS propagation take?
It depends on the TTL of the record you changed. Resolvers that cached the old record keep using it until its TTL runs out, then fetch the new one. A record with a 300-second TTL is replaced everywhere within about 5 minutes; one with a 86,400-second TTL can take up to a day. Lowering the TTL a day before a planned change makes the switch fast.
Does DNS use UDP or TCP?
Both, on port 53. Ordinary queries normally use UDP. TCP is used for zone transfers and when a response is too large for UDP, in which case the server sets the truncation (TC) flag and the client retries over TCP. RFC 7766 requires general-purpose DNS implementations to support both.
Why does nslookup say 'Non-authoritative answer'?
Because the answer came from your resolver's cache or its own lookup, not directly from a server that is authoritative for the domain. That is normal for everyday queries. To get an authoritative answer, add one of the domain's name servers to the command, for example nslookup larely.com vern.ns.cloudflare.com.

Sources