How to Fix DNS Caching Issues When Changing Domain IP: A Developer’s Guide


3 views

When you update your domain's DNS records (like changing the A record IP address), the changes don't take effect immediately worldwide. This delay is called DNS propagation, and it typically takes anywhere from a few minutes to 48 hours to complete globally.

Yes, your ISP is likely caching DNS records. Most ISPs implement DNS caching to:

  • Reduce latency for frequently visited websites
  • Lower bandwidth usage
  • Decrease load on their DNS servers

Before troubleshooting, verify if your changes have actually propagated:

# Linux/macOS
dig +short yourdomain.com
nslookup yourdomain.com

# Windows
nslookup yourdomain.com

Or use online tools like:

  • https://www.whatsmydns.net/
  • https://dnschecker.org/

Try these methods to bypass local DNS caching:

# Flush DNS cache on your local machine
# Windows
ipconfig /flushdns

# macOS
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

# Linux (systemd-resolved)
sudo systemd-resolve --flush-caches

Consider using public DNS servers that may have faster update cycles:

# Google DNS
8.8.8.8
8.8.4.4

# Cloudflare
1.1.1.1
1.0.0.1

Change your DNS settings programmatically:

# Python example to change DNS settings (Linux)
import subprocess

def change_dns(interface, dns_servers):
    for server in dns_servers:
        subprocess.run(['nmcli', 'con', 'mod', interface, 
                       f'ipv4.dns={server}'])
    subprocess.run(['nmcli', 'con', 'up', interface])

change_dns('eth0', ['8.8.8.8', '8.8.4.4'])

For future changes, lower your TTL (Time To Live) value in advance:

# Example DNS record with low TTL
$ORIGIN yourdomain.com.
@ 300 IN A 192.0.2.1  ; 300 seconds (5 minutes) TTL

Browsers also cache DNS. Force refresh with:

# Chrome/Edge address bar
chrome://net-internals/#dns

# Firefox
about:networking#dns

Here's a Python script to monitor DNS propagation:

import dns.resolver
import time

def check_dns_propagation(domain, expected_ip, timeout=48, interval=5):
    """
    Check if DNS has propagated to expected IP
    timeout: hours to wait
    interval: minutes between checks
    """
    resolver = dns.resolver.Resolver()
    resolver.nameservers = ['8.8.8.8']  # Use Google DNS
    
    end_time = time.time() + timeout * 3600
    while time.time() < end_time:
        try:
            answers = resolver.resolve(domain, 'A')
            for rdata in answers:
                if str(rdata) == expected_ip:
                    return True
        except Exception as e:
            print(f"Error: {e}")
        
        print(f"DNS not yet propagated. Waiting {interval} minutes...")
        time.sleep(interval * 60)
    
    return False

if check_dns_propagation('yourdomain.com', '192.0.2.1'):
    print("DNS propagated successfully!")
else:
    print("DNS propagation failed within timeout period")

When you modify your domain's DNS records in ZoneEdit or any DNS management console, the changes don't immediately reflect worldwide. This delay occurs because:

  • Your ISP's DNS servers cache previous records (TTL-based caching)
  • Intermediate DNS resolvers maintain their own caches
  • Global DNS propagation takes time (typically 24-48 hours)

Here's what happens at the protocol level when you update records:

// Simplified DNS query flow
1. Client Query → ISP DNS Resolver
   - Resolver checks local cache
   - If cached & TTL not expired: returns cached answer
2. No Cache → Recursive Resolution:
   a. Root Server → TLD Server → Authoritative Server
   b. Response stored in resolver cache (respecting TTL)

Use these command-line tools to check where your domain currently resolves:

# Linux/macOS
dig mydomain.com @8.8.8.8  # Query Google's DNS
dig mydomain.com @resolver1.opendns.com

# Windows
nslookup mydomain.com 8.8.8.8

Compare results from different DNS providers to see propagation status.

While you can't purge your ISP's cache, try these techniques:

// Programmatic DNS cache checking in Python
import socket
import dns.resolver

def check_dns(domain, nameserver='8.8.8.8'):
    resolver = dns.resolver.Resolver()
    resolver.nameservers = [nameserver]
    try:
        return [str(answer) for answer in resolver.resolve(domain, 'A')]
    except Exception as e:
        return str(e)
  • Lower TTL values (300-600 seconds) before making changes
  • Use DNS propagation checkers like whatsmydns.net
  • Implement health checks in your code to handle transition periods

For critical applications, consider this resilience pattern:

// JavaScript example of DNS fallback
async function resolveWithFallback(domain) {
  const dnsServers = ['1.1.1.1', '8.8.8.8', '9.9.9.9'];
  for (const server of dnsServers) {
    try {
      const response = await fetch(https://${server}/dns-query?name=${domain});
      return await response.json();
    } catch (error) {
      console.log(Failed with ${server}, trying next...);
    }
  }
  throw new Error('All DNS servers failed');
}