I'll never forget watching a retail client's error rate flatline to 100% at 2:17 AM because someone flipped the NS records before the new DNS provider had the full zone loaded. The CDN itself was healthy, the origins were fine, but resolvers simply couldn't find them. We spent the next four hours waiting out cached NS records we couldn't purge, and that night taught me you don't just change DNS providers — you choreograph a handoff where resolution continuity is non-negotiable.
The Hidden Dependencies That Make CDN DNS Changes Risky
When you're running traffic through a CDN, DNS isn't just a phone book, it's the steering wheel. Most CDN setups rely on a CNAME chain or delegated subdomains like cdn.example.com that point to the provider's Anycast edge, and that chain often includes alias records, load balancing logic, and geographic routing rules that don't exist in a standard BIND file. I've seen teams treat a CDN DNS change like swapping any other SaaS provider, only to discover their new authoritative servers weren't answering the _acme-challenge records for certificate renewal or the edge health checks the CDN uses to steer traffic. If you've mapped your current architecture against a Comprehensive CDN Migration Checklist: Every Step from Planning to Cutover, you know how many of those records are undocumented until they break.
Resolution continuity fails for boring reasons, not exotic ones. Old NS records live in resolver caches long after you've changed them at the registrar, negative caching hides missing records, and some ISP resolvers ignore your TTL entirely and hold onto data for hours. During one migration for a media company pushing 800 Gbps, we had 94% of queries hitting the new provider within 20 minutes, but a single regional ISP in Brazil kept serving the old delegation for six hours because they'd hard-coded a 24-hour minimum TTL. The CDN kept serving stale content to that region until we manually re-added the old zone. That's why a DNS migration plan has to assume both providers will be queried in parallel for at least 48 hours, and why your DNS switchover isn't complete when you change the delegation — it's complete when the last cached record expires.
#!/bin/bash
# compare authoritative vs. recursive resolution before cutover
DOMAINS=("www.example.com" "cdn.example.com" "api.example.com")
OLD_NS="ns1.old-provider.net"
NEW_NS="ns1.new-provider.net"
for domain in "${DOMAINS[@]}"; do
echo "=== $domain ==="
echo -n "OLD: "; dig +short @$OLD_NS $domain A | head -1
echo -n "NEW: "; dig +short @$NEW_NS $domain A | head -1
echo -n "PUBLIC (8.8.8.8): "; dig +short @8.8.8.8 $domain A | head -1
echo -n "PUBLIC (1.1.1.1): "; dig +short @1.1.1.1 $domain A | head -1
echo ""
done
# Check SOA serials match - they MUST be in sync
echo "SOA Serial Check:"
dig +short @$OLD_NS example.com SOA | awk '{print "OLD SOA:", $3}'
dig +short @$NEW_NS example.com SOA | awk '{print "NEW SOA:", $3}'
Building Parity Before You Touch the Delegation
The least glamorous part of a CDN DNS change is also the most important: making the new provider an exact mirror before anyone on the internet knows it exists. I start this work at least a week out, and the first move is always lowering TTLs. If your apex is sitting at 86400 seconds, drop it to 300 seconds 72 hours before migration, and do the same for any CNAMEs the CDN depends on. Yes, you'll increase query volume and your bill might tick up slightly, but that low TTL is your only escape hatch if you need to roll back. I learned this the hard way in 2019 when we tried to revert a failed migration with a 4-hour TTL — we were stuck watching 4 hours of SERVFAILs roll in. Don't skip this step, even if your product manager is pushing for a faster timeline.
Once TTLs are low, export the full zone from your current provider — including all the records you think you don't need — and import it into the new one, then verify parity byte-for-byte. Pay special attention to DNSSEC chains, ANAME/ALIAS records at the apex, and any provider-specific records like Cloudflare's proxied flags or Route 53 alias targets that won't translate one-to-one. You'll also want to confirm how the new provider handles EDNS Client Subnet and CNAME flattening, because two providers can both return "correct" answers that steer CDN traffic differently. We run automated comparisons for at least 48 hours in what I call shadow mode, where both sets of nameservers are authoritative but only the old one is delegated. If you're selecting a new provider right now, a rigorous CDN Vendor Evaluation Matrix: Scoring Providers on What Actually Matters should have already forced you to validate these edge behaviors, and your CDN RFP Template: Writing Requirements That Get Meaningful Vendor Responses should have documented them as requirements, not assumptions.
# Python: fail the build if zone records diverge
import dns.resolver
import dns.zone
from collections import Counter
OLD_NS = "ns1.old-provider.net"
NEW_NS = "ns1.new-provider.net"
ZONE = "example.com"
RECORD_TYPES = ["A", "AAAA", "CNAME", "TXT", "MX", "CAA"]
def get_records(ns, name, rdtype):
resolver = dns.resolver.Resolver()
resolver.nameservers = [OLD_NS if ns == OLD_NS else NEW_NS]
try:
answers = resolver.resolve(name, rdtype)
return sorted([r.to_text() for r in answers])
except Exception as e:
return [f"ERROR: {e}"]
mismatch = False
for rdtype in RECORD_TYPES:
old = get_records(OLD_NS, ZONE, rdtype)
new = get_records(NEW_NS, ZONE, rdtype)
if Counter(old) != Counter(new):
print(f"[MISMATCH] {ZONE} {rdtype}")
print(f" OLD -> {old}")
print(f" NEW -> {new}")
mismatch = True
if mismatch:
raise SystemExit("Zone parity check failed - do not cut over")
else:
print("All checked records in sync")
Executing the Cutover Without Losing a Query
With parity confirmed, the actual DNS switchover is anti-climactic if you've done the prep right. Don't do a hard flip of all NS records at once. Instead, update the delegation at your registrar to include nameservers from both providers for 24 to 48 hours — most TLDs allow up to 13 NS records, so you can run 2 old + 2 new concurrently. This dual-delegation period means resolvers will query whichever provider responds fastest, and if the new one has an issue, traffic naturally falls back without you touching anything. Only after your monitoring shows stable resolution from the new provider do you remove the old NS records. It feels slower, but I've never had a dual-delegation cutover cause an outage; I've had several single-flip cutovers cause one.
During that window, you're watching two things obsessively: authoritative query volume on both providers and recursive resolution success from the outside. Your new provider's dashboard should show query share climbing from 0% to roughly 50% within an hour and to 90%+ within the old TTL window. At the same time, you should be running synthetic checks from RIPE Atlas, Catchpoint, or even simple cron jobs on VMs in different networks that query public resolvers every 30 seconds. If you see SERVFAILs or inconsistent answers between 8.8.8.8, 1.1.1.1, and 9.9.9.9, pause and investigate before you remove the old delegation. The HTTP Working Group Specifications (https://httpwg.org/specs/) and web.dev Articles (https://web.dev/articles/) both emphasize that CDN performance is bounded by DNS reliability, and a 0.5% resolution failure rate will dwarf any cache hit ratio optimization you've done.
Keep your old provider's zone active and unmodified for at least seven days after you think you're done. I've seen teams delete the old zone on day two to save costs, then discover a forgotten internal tool was hardcoded to query the old nameserver IP directly. Set a calendar reminder, keep paying for those two extra days, and define a clear rollback trigger: if error rates exceed your baseline by more than 0.1% or if any synthetic monitor fails for five consecutive minutes, revert the delegation. Having that decision made before you're tired and stressed is what keeps a DNS migration boring — and boring is exactly what you want.
| Signal to Monitor | Healthy Pre-Cutover Value | Safe to Remove Old NS | How to Measure |
|---|---|---|---|
| SOA Serial Sync Lag | 0 - 60 seconds | < 60 seconds for 24h straight | dig @old + @new SOA compare serial |
| Post-Cutover Validation: Proving Every Query Still Resolves
Flipping the NS delegation at your registrar is the easy part. Proving that the new provider is actually serving clean answers to 100% of your query mix is where most teams get caught out. Don't trust the provider's dashboard — it only tells you what it's configured to serve, not what resolvers are actually getting. For the first 72 hours post-cutover, you need active, external validation running every 30 to 60 seconds from distributed vantage points. We've seen migrations that looked green in the portal but were dropping 2-4% of queries for EDNS0 clients in Southeast Asia because of a misconfigured UDP payload size. Your validation stack should compare answers from the old and new authorities in parallel, even after you've changed the delegation. Keep the old zone active (but not authoritative) for at least 7 days and hammer both with the same query set: A, AAAA, CNAME, TXT, and crucially, your CDN's edge hostnames. Check for more than just an answer — validate TTLs, AA flags, and response consistency across all of the new provider's nameservers. If you're running a CDN Pilot Testing Methodology: Metrics, Duration, and Success Criteria in parallel, this is the perfect time to correlate DNS resolution time (target p95 under 35ms) with cache hit ratio and origin fetch latency. A 20ms DNS regression won't trip an alert on its own, but it'll add 200-300ms to your cold-start TTFB. The cheapest mistake is to decommission the old provider too early. Keep it paid and serving until the parent zone's NS TTL plus twice the old zone's SOA expire value has fully elapsed — typically 48 to 96 hours minimum. That gives every recursive resolver on the planet time to expire its delegation cache. Only then should you remove the zone.
Troubleshooting Stale Delegations and Silent FailuresWhen something breaks during a CDN DNS migration, it rarely breaks loudly. You won't get a 500 error; you'll get a slow leak of SERVFAILs and timeouts that your synthetic monitor in us-east-1 never sees. The two patterns we debug most often are lame delegations and inconsistent apex handling. A lame delegation happens when the parent zone (your TLD's nameservers) still points to an old NS that you've already deleted or that now returns REFUSED. Resolvers that cached that delegation will try the dead NS first, wait the full 2-5 second timeout, then retry. To the end user it feels like the site is just... slow. You'll see it as a 15-30% increase in p95 DNS lookup time in your RUM data before you see any hard failures. The second gotcha is how your new provider handles the zone apex and CDN CNAME flattening. Some anycast DNS providers automatically flatten a CNAME at the apex to A/AAAA records for you, others require an explicit ANAME or ALIAS record, and a few will just refuse to let you put a CNAME at the apex at all. If you lift-and-shift a zone file that had `example.com. 300 IN CNAME cdn-provider.net.` you'll get a hard validation failure on import with the stricter providers, and queries for the apex will return NXDOMAIN. We've had to roll back two enterprise cutovers for exactly this reason. Test apex resolution explicitly with `dig example.com @new-provider +norecurse` and `dig example.com A +short` from an external resolver like 8.8.8.8, not just from the provider's own NS. If you're still evaluating providers, treat this as a core test case in your CDN Proof of Concept Planning: Designing a PoC That Answers Real Questions — don't discover it on cutover night. If you do hit inconsistent resolution, don't panic and flip the registrar back immediately — that'll just extend the inconsistency window due to the parent TTL (often 172,800 seconds). Instead, fix forward on the new provider and lower the TTL on any corrected records to 60 seconds to force faster convergence. For a full rollback strategy when the new provider is fundamentally unhealthy, follow a rehearsed CDN Traffic Cutover Strategy: Migrating Without Downtime or Data Loss that keeps both control planes warm and DNSSEC signing keys in sync. And if you signed your zone with DNSSEC, remember: a botched KSK rollover during migration is unrecoverable for validating resolvers until the DS TTL expires. Never change DNS provider and rotate DNSSEC keys in the same window. Frequently Asked QuestionsHow long should I run both DNS providers in parallel?At an absolute minimum, 7 days. You need to cover the longest TTL in your chain: the parent NS TTL (usually 48 hours) plus your zone's SOA expire and negative cache TTL. We recommend 14 days for high-traffic zones. Keep the old zone answering correctly the entire time, just remove its NS from the parent delegation. The $300/month you save by shutting it off early isn't worth the risk of a resolver with a stale delegation hitting a dead end. Do I need to lower TTLs before the migration?Yes, and do it early. Drop all critical A, AAAA, and CNAME TTLs to 300 seconds at least twice the old TTL value before your planned cutover — so if your current TTL is 3600s, lower it 72 hours in advance. Do the same for your NS records if your provider allows it. After you've validated the new provider for 48-72 hours with no parity errors, you can raise TTLs back to 3600s or higher to reduce query volume and improve resilience. Will changing DNS providers affect my CDN caching or performance?DNS itself doesn't purge the edge cache, but it changes how users map to CDN edges. If your new provider has different anycast PoPs or geo-routing logic, users may suddenly resolve to a different CDN edge — often a more distant one for the first few hours. Pre-warm the cache on all major CDN PoPs before cutover and watch your cache hit ratio closely. A 5-8% dip in hit ratio for 2-4 hours post-cutover is normal; a 20%+ drop means your DNS geo-steering is misconfigured. What’s the safest way to handle DNSSEC during a provider move?Use a double-signing, pre-publish method. Publish the new provider's DNSKEY in your old zone first, wait for that TTL to expire, then publish the DS record for the new KSK at your registrar, wait another TTL cycle, and only then change the NS delegation. Never do a “flag day” switch where you change NS and DS at the same time. Validating resolvers like Google Public DNS will hard-fail your domain with SERVFAIL if the DS doesn't match the DNSKEY they see, and that failure is cached for the DS TTL. External ReferencesRelated Articles
References & Standards: HTTP Working Group Specifications · web.dev Articles · IETF Datatracker |