DNS Demystified 5: TTL, Propagation, /etc/hosts, and Linux Resolution Order
“It will take 24-48 hours to propagate.” Every sysadmin has heard this. Most of the time, it is wrong. This article explains what actually happens when you change a DNS record, and shows you tools to control resolution order on Linux.
TTL is a number in seconds that tells recursive resolvers how long to cache a DNS record. It is set by the zone owner on each individual record (or globally via $TTL in the zone file).
rootlog.in. 300 IN A 185.199.108.153
^^^
TTL = 300 seconds (5 minutes)
The TTL is specified in the RDATA section of every RR — it is not a separate field. The resolver reads the TTL from the response and sets its cache timer accordingly. The countdown starts from the moment the response is received, not from the moment the zone file was last updated.
Reference: RFC 1035 section 4.1.3 — TTL field in resource record format. Reference: RFC 2308 — Negative Caching of DNS Queries (NCACHE), defines how NXDOMAIN responses are cached.
| Record Type | Typical TTL | Rationale |
|---|---|---|
| A/AAAA (production) | 300-3600 | Balance between stability and change speed |
| A/AAAA (CDN) | 60-300 | Fast failover for CDN endpoints |
| MX | 3600-86400 | Email servers rarely change IP |
| TXT (SPF/DKIM) | 3600-86400 | Infrequent changes |
| NS | 86400-172800 | Rarely changes, high cost of stale data |
| SOA minimum | 300-3600 | Controls negative caching (NCACHE, RFC 2308) |
Pro tip: Do not use 86400 (24h) TTL for A records unless the IP is truly static. If your server IP changes and the TTL is 24 hours, you will have downtime for a full day. Start with 300 and increase to 3600 once you are confident the record is stable. CDNs often use 60 seconds or less.
There is no such thing as “DNS propagation” in the way most people describe it. There is no central authority that pushes changes to all resolvers. Here is what actually happens when you update a DNS record:
So the delay is not propagation — it is cache expiry on each individual resolver. There is no push mechanism. There is no central update. Every resolver independently waits out its local copy of the TTL.
Before changing a production record:
dig +ttlid from multiple locations.# Step 1: Check current TTL
dig rootlog.in +ttlid
# Step 2: After TTL reduction, verify authoritative
dig @dns1.p01.nsone.net rootlog.in +short
# Step 3: Check that recursive resolvers have picked up the change
dig @1.1.1.1 rootlog.in +short
dig @8.8.8.8 rootlog.in +shortReal-world context: The “24-48 hour propagation” myth persists because registrars and DNS providers set default TTLs of 86400 (24h) or even 172800 (48h). When a user changes a record without first reducing the TTL, they end up waiting 24-48 hours for caches to expire. This is not propagation — it is the predictable consequence of a high TTL. Set TTLs low before making changes.
The /etc/hosts file (man 5 hosts) maps hostnames to IP addresses directly, bypassing DNS entirely.
127.0.0.1 localhost
127.0.1.1 myhost
185.199.108.153 rootlog.in
192.168.1.50 nas.lan
0.0.0.0 doubleclick.net
Reference:
man 5 hosts— the hosts file format. Reference: RFC 952 — hostname specifications (the original DARPA standard).
Blocking domains — Redirect unwanted domains to localhost or 0.0.0.0:
0.0.0.0 ads.example.com
0.0.0.0 tracking.example.com
Using 0.0.0.0 causes the connection to fail immediately (no route to host) rather than waiting for a timeout. Many system-wide ad-blockers like Pi-hole operate at the DNS level, but a simple /etc/hosts file works for individual machines.
Local development — Override production domains to point to local servers:
127.0.0.1 myapp.local
127.0.0.1 api.myapp.local
Network isolation — Bypass DNS for critical infrastructure during failures:
10.0.0.1 ns1.internal.company.com
10.0.0.2 ns2.internal.company.com
Bypassing DNS blocking — Some ISPs block domains at the DNS level. If you know the IP, add it to /etc/hosts.
Pro tip: The
0.0.0.0address for blocking is deliberate — it is not a valid destination IP, so connections fail instantly with “Network is unreachable.” Do not use127.0.0.1for blocking, as it creates a connection to a local service that may exist, and the application will wait for a timeout.
IP_ADDRESS CANONICAL_NAME [ALIASES...]
Multiple hostnames can map to the same IP:
127.0.0.1 localhost.localdomain localhost dev.local
Linux does not query DNS directly. It uses a configurable resolution order defined in /etc/nsswitch.conf (man 5 nsswitch.conf). The relevant line:
hosts: files dns mdns4
This tells the system to check name resolution sources in order:
/etc/hosts first/etc/resolv.confReference:
man 5 nsswitch.conf— the full Name Service Switch configuration reference. Reference:man 3 gethostbyname— the glibc function that implements this lookup.
When an application calls gethostbyname("rootlog.in"):
/etc/nsswitch.confhosts: files dnsnss_files module — checks /etc/hosts line by linenss_dns module — queries DNS# Trace the actual resolution path used by the system
strace -e trace=open,read getent hosts rootlog.in 2>&1 | grep "hosts\|resolv"You will see glibc opening /etc/hosts first, then /etc/resolv.conf.
Prioritise DNS over /etc/hosts (not recommended — reduces security):
hosts: dns files
Add mdns after DNS:
hosts: files dns mdns4_minimal [NOTFOUND=return] mdns4
Disable DNS entirely (air-gapped systems):
hosts: files
getent hosts rootlog.ingetent follows the same nsswitch resolution order as every other application. Use it to verify what the system will actually resolve:
getent hosts rootlog.in # follows nsswitch order — checks /etc/hosts first
dig +short rootlog.in # always queries DNS directly (bypasses nsswitch)Pro tip: If
getent hostsanddigreturn different results,/etc/hostshas an entry that is overriding DNS. This is a common source of “why does this server see a different IP for my domain?”
VPN clients often add internal domains to /etc/hosts. If a VPN entry points to a stale IP, it silently overrides DNS for that domain — no TTL to expire, no cache to clear. The only fix is manually editing /etc/hosts.
Docker containers inherit the host’s /etc/resolv.conf but have their own /etc/hosts. Docker’s embedded DNS server (127.0.0.11) handles container name resolution. If you override a container hostname in /etc/hosts, Docker’s DNS is bypassed entirely.
Real-world context: This is a common issue in Kubernetes pods. The pod’s
/etc/hostsis managed by the kubelet, and the pod’s/etc/resolv.confpoints to the cluster DNS service (e.g.,kube-dns). If an init script modifies/etc/hostsinside the pod, it can silently break resolution for any hostname that matches the entry.
On systemd systems, /etc/resolv.conf often points to 127.0.0.53 — the systemd-resolved stub. This adds an additional caching layer between the application and the actual DNS servers. systemd-resolved maintains its own cache, which may serve stale data even after the upstream TTL has expired.
Flush it:
resolvectl flush-cachesOlder Linux systems run nscd, which caches hosts entries including /etc/hosts lookups. If you edit /etc/hosts, nscd may serve the old entry:
nscd -i hosts # invalidate the hosts cacheCreate a test entry in /etc/hosts:
127.0.0.2 test-resolution-order.com
Then compare:
getent hosts test-resolution-order.com # returns 127.0.0.2 from /etc/hosts
dig +short test-resolution-order.com # returns real IP from DNS (or NXDOMAIN)The difference confirms that /etc/hosts is checked first by getent but dig bypasses it entirely.
/etc/hosts (man 5 hosts) overrides DNS and is checked first by the standard resolution order (hosts: files dns)./etc/nsswitch.conf (man 5 nsswitch.conf) controls the resolution order — change it to customise the lookup sequence.getent hosts to see what the system will actually resolve (it follows nsswitch).dig to bypass nsswitch and query DNS directly.resolvectl flush-caches) and nscd (nscd -i hosts) add caching layers that may serve stale data.man 5 hosts — the hosts file format and location.man 5 nsswitch.conf — Name Service Switch configuration.man 5 resolv.conf — resolver configuration format.man 8 systemd-resolved — systemd DNS stub resolver.man 8 nscd — Name Service Cache Daemon.In the final article of this series, we will build our own DNS server with BIND for the rootlog.in domain.
Related Articles
DNS Demystified 7: Third-Party DNS Providers and Nameserver Management
When to use managed DNS vs self-hosted, how to switch nameservers, and a comparison of Cloudflare, Route53, Google Cloud DNS, NS1, and dnsimple.
DNS Demystified 6: Building Your Own DNS Server for rootlog.in
Types of DNS servers and a step-by-step guide to setting up BIND9 as an authoritative nameserver for the rootlog.in domain.
DNS Demystified 5: TTL, Propagation, /etc/hosts, and Linux Resolution Order
TTL mechanics, propagation delay myth-busting, /etc/hosts tricks, and the Linux name resolution order via nsswitch.conf.