DNS (Domain Name System) is a distributed hierarchical database that translates human-readable domain names (like example.com) into machine-readable IP addresses (like 93.184.216.34).
Without DNS, you'd have to remember 142.250.185.46 instead of google.com!
Why DNS Exists: IP addresses are hard to remember. Domain names are easy. DNS bridges the gap.
DNS is organized in a tree-like hierarchy:
. (Root)
|
┌───────────────┼───────────────┐
| | |
.com .org .net ← Top-Level Domains (TLDs)
| | |
| | |
example.com wikipedia.org archive.net ← Second-Level Domains
|
|
www.example.com ← Subdomains
api.example.com
staging.example.com
Full DNS Query Path:
www.example.com → .com → example.com → www
Each level is managed by different nameservers.
When you type a URL in your browser, a complex but fast process happens behind the scenes:
Your browser first checks its own DNS cache. If you recently visited the site, the IP is cached here.
chrome://net-internals/#dnsIf not in browser cache, check OS-level DNS cache.
Before querying DNS servers, the OS checks the hosts file - a local override file.
Priority: Hosts file entries override DNS! This is crucial for local development.
If not found locally, your computer queries the configured DNS resolver (usually your ISP or public DNS).
The resolver either has the answer cached or performs a recursive query.
If resolver doesn't have the answer, it performs a full DNS query:
The resolver caches the result (based on TTL - Time To Live) and returns the IP to your computer.
Your OS and browser also cache it for future requests.
User types: www.example.com in browser
┌─────────────────┐
│ 1. Browser Cache│ ─── Hit? → Return IP (done in <1ms)
└─────────────────┘ │
│ Miss
▼ │
┌─────────────────┐ │
│ 2. OS Cache │ ─── Hit? → Return IP (done in ~1ms)
└─────────────────┘ │
│ Miss
▼ │
┌─────────────────┐ │
│ 3. Hosts File │ ─── Found? → Return IP (highest priority!)
└─────────────────┘ │
│ Not found
▼ │
┌─────────────────┐ │
│ 4. DNS Resolver │◄──────┘
│ (8.8.8.8) │
└─────────────────┘
│
▼
Has cached answer? ─── Yes → Return IP (done in ~10-20ms)
│
No
│
▼
┌─────────────────────────────────────────┐
│ 5. Recursive Query (if not cached) │
│ │
│ DNS Resolver → Root Server │
│ ↓ │
│ Root Server: "Ask .com TLD server" │
│ ↓ │
│ Resolver → .com TLD Server │
│ ↓ │
│ TLD Server: "Ask example.com's NS" │
│ ↓ │
│ Resolver → example.com Authoritative │
│ ↓ │
│ Authoritative: "93.184.216.34" │
└─────────────────────────────────────────┘
│
▼
┌─────────────────┐
│ 6. Cache Result │ (TTL: 300s - 86400s)
│ Return to User│
└─────────────────┘
│
▼
Browser connects to 93.184.216.34
Total Time: 1-100ms depending on cache hits
DNS stores different types of records for different purposes:
| Record Type | Purpose | Example |
|---|---|---|
| A | Maps domain to IPv4 address | example.com → 93.184.216.34 |
| AAAA | Maps domain to IPv6 address | example.com → 2606:2800:220:1:248:1893:25c8:1946 |
| CNAME | Creates alias (points to another domain) | www.example.com → example.com |
| MX | Specifies mail servers | example.com → mail.example.com (priority 10) |
| TXT | Stores arbitrary text data | SPF records, domain verification, DKIM |
| NS | Specifies authoritative nameservers | example.com → ns1.example.com, ns2.example.com |
| SOA | Start of Authority (domain metadata) | Primary nameserver, admin email, serial number, refresh/retry timers |
| PTR | Reverse DNS (IP to domain) | 93.184.216.34 → example.com |
| SRV | Service locator (protocol-specific) | _ldap._tcp.example.com → server:port |
| CAA | Certificate Authority Authorization | Specifies which CAs can issue SSL certificates |
# Using nslookup (Windows/Mac/Linux) nslookup example.com # Output shows A records (IPv4 addresses) # Query specific record type nslookup -type=MX google.com # Shows mail server records # Using dig (Mac/Linux - more detailed) dig example.com # Shows A records with TTL and more details dig example.com AAAA # Query IPv6 records dig example.com ANY # Query all record types (not always supported) # Trace full DNS resolution path dig +trace example.com # Shows root → TLD → authoritative server path # Query specific DNS server dig @8.8.8.8 example.com # Query Google DNS specifically
The hosts file is a plain text file on your computer that maps domain names to IP addresses. It's checked BEFORE DNS queries, giving you local control over domain resolution.
Priority: Hosts File > DNS Cache > DNS Servers
Use Cases: Local development domains, blocking websites, testing before DNS changes go live, bypassing DNS issues.
Location: C:\Windows\System32\drivers\etc\hosts
Important: No file extension! It's named exactly "hosts" not "hosts.txt"
# View hosts file type C:\Windows\System32\drivers\etc\hosts # Edit with Notepad (requires admin) # Right-click Notepad → "Run as administrator" # Then open: C:\Windows\System32\drivers\etc\hosts # Or use PowerShell notepad C:\Windows\System32\drivers\etc\hosts
Location: /etc/hosts or /private/etc/hosts (same file, symlinked)
# View hosts file cat /etc/hosts # Edit with nano (requires sudo) sudo nano /etc/hosts # Or use vim sudo vim /etc/hosts # Or open in TextEdit sudo open -e /etc/hosts
Location: /etc/hosts
# View hosts file cat /etc/hosts # Edit with nano sudo nano /etc/hosts # Edit with vim sudo vim /etc/hosts # Edit with gedit (GUI) sudo gedit /etc/hosts
# Hosts file syntax: IP_ADDRESS DOMAIN_NAME [ALIAS...] # Lines starting with # are comments # Default localhost entries (always present) 127.0.0.1 localhost ::1 localhost # Custom local development domains 127.0.0.1 myapp.local 127.0.0.1 api.myapp.local 127.0.0.1 staging.myapp.local # Multiple aliases on one line 127.0.0.1 dev.local app.dev myproject.test # Block websites (redirect to nowhere) 0.0.0.0 example-ad-network.com 0.0.0.0 tracking-site.com # Point domain to different IP (useful for testing) 192.168.1.100 production-site.com # IPv6 entries ::1 myapp.local # IMPORTANT RULES: # - Use tabs or spaces (tabs preferred) # - One entry per line # - Case-insensitive domain names # - No wildcards (* not supported) # - Changes take effect immediately (but flush DNS cache)
Windows:
C:\Windows\System32\drivers\etc\macOS/Linux:
sudo nano /etc/hosts
At the end of the file, add your custom domain mapping:
127.0.0.1 myapp.local
Best Practices:
.local, .test, or .localhost TLDs (reserved for local use).dev (requires HTTPS - Google owns .dev TLD)Windows Notepad: File → Save (Ctrl+S)
nano: Ctrl+O (write out), Enter, Ctrl+X (exit)
vim: :wq (write and quit)
For changes to take effect in your browser, flush DNS cache:
# Windows ipconfig /flushdns # macOS (Big Sur and later) sudo dscacheutil -flushcache sudo killall -HUP mDNSResponder # Linux with systemd sudo systemd-resolve --flush-caches # Linux with nscd sudo service nscd restart # Linux with dnsmasq sudo service dnsmasq restart
Browsers maintain their own DNS cache. Clear it or restart browser:
chrome://net-internals/#dns → "Clear host cache"edge://net-internals/#dns → "Clear host cache"# Test DNS resolution ping myapp.local # Should resolve to 127.0.0.1 and show successful pings # Or use nslookup (may not respect hosts file on some systems) nslookup myapp.local
Then open http://myapp.local:3000 in your browser (assuming your dev server is on port 3000).
Using custom domains like myapp.local instead of localhost:3000 provides a more professional development experience and enables testing subdomain-based features.
myapp.local vs localhost:3000api.myapp.local, admin.myapp.localStep 1: Edit Hosts File
127.0.0.1 myapp.local 127.0.0.1 api.myapp.local
Step 2: Flush DNS Cache
ipconfig /flushdns # Windows sudo killall -HUP mDNSResponder # macOS
Step 3: Configure Your Development Servers
React (package.json):
{
"scripts": {
"start": "HOST=myapp.local PORT=3000 react-scripts start"
}
}
Express API (server.js):
const express = require('express');
const app = express();
app.listen(4000, () => {
console.log('API running at http://api.myapp.local:4000');
});
Step 4: Configure Reverse Proxy (Optional but Recommended)
Use Nginx or Apache to remove port numbers:
# /etc/nginx/sites-available/myapp.local
server {
listen 80;
server_name myapp.local;
location / {
proxy_pass http://localhost:3000;
}
}
server {
listen 80;
server_name api.myapp.local;
location / {
proxy_pass http://localhost:4000;
}
}
Step 5: Access Your App
http://myapp.local (if using reverse proxy) or http://myapp.local:3000http://api.myapp.local (if using reverse proxy) or http://api.myapp.local:4000Avoid: .dev (owned by Google, requires HTTPS), .app (requires HTTPS), real TLDs like .com or .net
DNS caching improves performance but can cause confusion when testing DNS changes. Understanding and managing DNS cache is essential for developers.
Implication: Flushing your OS cache won't clear upstream caches. DNS propagation can take time due to these multiple layers.
# ======================================== # WINDOWS # ======================================== # Flush DNS cache ipconfig /flushdns # Display DNS cache contents (before flushing) ipconfig /displaydns # ======================================== # macOS # ======================================== # macOS Big Sur (11) and later sudo dscacheutil -flushcache sudo killall -HUP mDNSResponder # macOS Catalina (10.15) and earlier sudo killall -HUP mDNSResponder # ======================================== # LINUX # ======================================== # systemd-resolved (Ubuntu 18.04+, most modern distros) sudo systemd-resolve --flush-caches # Or sudo resolvectl flush-caches # Check systemd-resolved status sudo systemd-resolve --statistics # nscd (older systems or RHEL/CentOS) sudo service nscd restart # Or sudo /etc/init.d/nscd restart # dnsmasq (if using dnsmasq) sudo service dnsmasq restart # Or sudo /etc/init.d/dnsmasq restart # If no DNS cache daemon, nothing to flush # (Some minimal Linux systems don't cache DNS) # ======================================== # BROWSER DNS CACHE # ======================================== # Chrome/Edge: Navigate to chrome://net-internals/#dns # Click "Clear host cache" # Firefox: Restart browser or: # about:config → network.dnsCacheExpiration = 0 (temporarily) # Safari: Clear history or quit and reopen
dig @8.8.8.8 yourdomain.com or nslookup yourdomain.com 8.8.8.8 to query a public DNS server directly, bypassing all local caches. This tells you if DNS has propagated globally, even if your local cache is stale.
Error: "This site can't be reached" or "Server not found"
Causes:
Solutions:
# Check if domain exists nslookup yourdomain.com # Query authoritative nameserver directly dig @ns1.yourdomain.com yourdomain.com # Check domain registration whois yourdomain.com
Error: Domain resolves but to wrong server
Causes:
Solutions:
# 1. Check hosts file first cat /etc/hosts # Mac/Linux type C:\Windows\System32\drivers\etc\hosts # Windows # 2. Flush all DNS caches ipconfig /flushdns # Windows sudo killall -HUP mDNSResponder # macOS # 3. Query public DNS to check propagation dig @8.8.8.8 yourdomain.com dig @1.1.1.1 yourdomain.com # 4. Clear browser cache # chrome://net-internals/#dns → Clear host cache
Error: Timeout or "DNS server not responding"
Causes:
Solutions:
# Check current DNS server ipconfig /all # Windows - look for "DNS Servers" cat /etc/resolv.conf # Linux/Mac # Switch to public DNS # Google DNS: 8.8.8.8, 8.8.4.4 # Cloudflare DNS: 1.1.1.1, 1.0.0.1 # Test with specific DNS server nslookup google.com 8.8.8.8 # Check if port 53 is reachable telnet 8.8.8.8 53
Error: myapp.local doesn't resolve after editing hosts file
Solutions:
# Correct format (space or tab between IP and domain) 127.0.0.1 myapp.local # Incorrect (no space) 127.0.0.1myapp.local # Incorrect (wrong IP) localhost myapp.local
ping myapp.local
# Should reply from 127.0.0.1
.local is reserved for Bonjour/mDNS. Use .localhost or .test instead.# ======================================== # nslookup - Basic DNS lookup (Windows/Mac/Linux) # ======================================== nslookup google.com # Shows IP addresses (A records) nslookup -type=MX google.com # Query mail server records nslookup google.com 8.8.8.8 # Query specific DNS server # ======================================== # dig - Detailed DNS information (Mac/Linux) # ======================================== dig google.com # Detailed A record query with TTL dig google.com AAAA # Query IPv6 records dig google.com MX # Query mail server records dig +short google.com # Show only IP address (concise) dig +trace google.com # Trace DNS resolution path from root servers dig @8.8.8.8 google.com # Query Google DNS specifically dig -x 8.8.8.8 # Reverse DNS lookup (IP to domain) # ======================================== # host - Simple DNS lookup (Mac/Linux) # ======================================== host google.com # Quick DNS lookup host -t MX google.com # Query specific record type # ======================================== # Check DNS Server Configuration # ======================================== # Windows ipconfig /all | findstr "DNS Servers" # macOS/Linux cat /etc/resolv.conf # Or scutil --dns # macOS # ======================================== # Test DNS Propagation # ======================================== # Query multiple public DNS servers dig @8.8.8.8 yourdomain.com # Google dig @1.1.1.1 yourdomain.com # Cloudflare dig @208.67.222.222 yourdomain.com # OpenDNS
A: No. The hosts file does not support wildcards. You cannot use *.myapp.local to match all subdomains. You must add each subdomain explicitly:
127.0.0.1 myapp.local 127.0.0.1 api.myapp.local 127.0.0.1 admin.myapp.local
For wildcard DNS, you need a local DNS server like dnsmasq.
A: Use dnsmasq (Linux/Mac) or Acrylic DNS Proxy (Windows). Example with dnsmasq:
# Install dnsmasq (Mac) brew install dnsmasq # Configure wildcard echo "address=/.local/127.0.0.1" >> /usr/local/etc/dnsmasq.conf # Start dnsmasq sudo brew services start dnsmasq # Configure system to use dnsmasq sudo mkdir -p /etc/resolver echo "nameserver 127.0.0.1" | sudo tee /etc/resolver/local
Now all *.local domains resolve to 127.0.0.1.
A: Some browsers and apps use DNS over HTTPS (DoH) which bypasses the hosts file. To fix:
Alternatively, some apps hard-code DNS servers (like 8.8.8.8) and ignore system DNS settings entirely.
A: localhost is a hostname that resolves to a loopback IP address. 127.0.0.1 is the actual IPv4 loopback address.
localhost can resolve to 127.0.0.1 (IPv4) or ::1 (IPv6) depending on system configurationlocalhost might try ::1 first127.0.0.1 explicitly forces IPv4, avoiding any IPv6 issuesA: DNS propagation depends on TTL (Time To Live) values:
A: Yes! Redirect ad domains to 0.0.0.0 (or 127.0.0.1):
0.0.0.0 ads.example.com 0.0.0.0 tracker.example.com 0.0.0.0 malware-site.com
This prevents your computer from connecting to those domains. However:
There are community-maintained hosts files with thousands of ad/tracker domains: Steven Black's hosts