You type github.com and hit enter. The page loads in under a second. Simple, right?
Not really. Before your browser sends a single request to GitHub's server, it first has to figure out where that server actually is. Domains are just human-readable names. Computers talk in IP addresses. Something has to translate one to the other. That is what DNS does.
Here is every step of that translation, in order.
How a domain becomes an IP address
Press Play to watch the full DNS resolution, or step through manually.
Step 1 — Browser checks its own cache
The very first thing your browser does is look at its own cache. It keeps a list of domains it has already looked up recently along with their IP addresses. If github.com is in there and the record has not expired, it skips everything else and goes directly to the server.
No network call. Instant.
If it is not cached, the browser makes a system call called getaddrinfo. This hands the problem over to the operating system.
Step 2 — OS checks the hosts file
Before the OS reaches out to any DNS server, it checks a local file on your hard drive called the hosts file. On Linux and macOS this is at /etc/hosts. On Windows it is at C:\Windows\System32\drivers\etc\hosts.
This file can have manual domain-to-IP mappings. If your domain is in there, the OS returns that IP directly. No network involved at all.
127.0.0.1 localhost
192.168.1.10 myapp.localDevelopers use this a lot for local development. You can point a domain like myapp.local to your own machine and your browser will use it like a real domain.
If the hosts file does not have the domain either, the OS sends the query out to a DNS server.
Step 3 — Query hits the Recursive Resolver
Your OS sends the DNS query to your ISP's DNS server. This server is called the Recursive Resolver. Every internet provider runs one of these. You can also use public ones like 8.8.8.8 from Google or 1.1.1.1 from Cloudflare.
The Recursive Resolver is the one doing all the heavy lifting. It is the middleman that talks to the rest of the DNS system on your behalf. If it already has the answer cached from a previous lookup, it returns the IP immediately.
If not, it starts a chain of queries.
Step 4 — Recursive Resolver asks the Root nameserver
The Resolver starts from the very top of the DNS hierarchy and asks a Root nameserver.
There are only 13 Root nameserver addresses in the world, though they are actually spread across hundreds of physical machines globally. Root nameservers do not know the IP address of your domain. What they know is where to find the nameserver responsible for top level domains.
Query: "Where is github.com?"
Answer: "I don't know. But here is who handles .com"
Root returns the address of the TLD nameserver for .com.
Step 5 — Recursive Resolver asks the TLD nameserver
The Resolver now contacts the TLD (top level domain) nameserver. This server handles everything under .com, .org, .net, and so on.
Again it does not know the final IP. But it knows who is authoritative for github.com specifically. It returns the address of GitHub's own nameserver.
Query: "Where is github.com?"
Answer: "I don't know the IP. But here is GitHub's nameserver"
Step 6 — Recursive Resolver asks the Authoritative nameserver
This is the last stop. The Authoritative nameserver is the one that actually holds the DNS records for the domain. GitHub manages this themselves. It has the exact IP address mapped to github.com.
Query: "Where is github.com?"
Answer: "140.82.121.4"
The Authoritative nameserver returns the IP to the Recursive Resolver.
Step 7 — Everything gets cached and the browser connects
The Recursive Resolver caches this result. Every DNS record has a TTL (time to live) value that tells caches how long to keep it. Next time anyone on your ISP looks up github.com, the Resolver answers from its cache without going through steps 4, 5, and 6 again.
The Resolver sends the IP back to your browser. The browser caches it too. And finally, your browser opens a TCP connection to that IP and sends the actual HTTP request.
The whole DNS lookup takes somewhere between a few milliseconds if the Resolver has it cached, up to around 100 to 200 milliseconds if it has to go through the full chain. For most requests you never notice because the browser has already cached the IP from a previous visit.
The full picture
Browser cache → hosts file → Recursive Resolver cache
→ Root NS → TLD NS → Authoritative NS
→ IP returned → cached at Resolver → cached at Browser
→ TCP connection → HTTP request
Every layer caches to avoid repeating the work. That is the whole design. DNS is fast because most of the time you never have to go past the first or second cache.
Why this matters for developers
A few practical things that come out of knowing this.
When you change a domain's DNS records, it does not update instantly for everyone. Old IP addresses stay cached at Resolvers and in browsers until the TTL expires. That is why DNS changes can take a few minutes to a few hours to propagate. If you are debugging why your domain is not pointing to the new server yet, check the TTL of your records.
You can flush your local DNS cache to force a fresh lookup.
# macOS
sudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder
# Linux (systemd)
sudo systemd-resolve --flush-caches
# Windows
ipconfig /flushdnsAnd if you want to manually trace the full DNS resolution path for any domain you can use dig with the trace flag.
dig github.com +traceThis shows you every step from Root to Authoritative, the same chain the Recursive Resolver walks. Really useful when you are troubleshooting DNS issues or just want to see exactly what is happening.
DNS is one of those things that just works quietly in the background all the time. But understanding the steps makes a lot of other things clearer, like why DNS propagation takes time, how you can override domains locally for development, and why switching to a faster DNS provider like 1.1.1.1 can shave a few milliseconds off every fresh lookup.