Skip to main content

DNS Cutover Checklist for Web App Deploys: TTL Prep, dig Checks, and Zero-Downtime Flips

A step-by-step DNS cutover checklist for moving a web app: when to drop TTLs, choosing between A, AAAA, CNAME and ALIAS, verifying with dig, and rolling back fast.

Published By Li Lei
#dns #deployment #devops #migration

DNS Cutover Checklist for Web App Deploys: TTL Prep, dig Checks, and Zero-Downtime Flips

Moving a web app to new infrastructure is mostly boring right up until the DNS flip. The new servers are provisioned, the database is replicated, the load balancer answers health checks — and then one record change decides whether users glide over or half of them spend an hour hitting the dead origin. The good news: a DNS cutover is a checklist problem, not a luck problem. This post walks through the checklist I use, in order, with the exact dig commands to verify each step. If any record type below is unfamiliar, paste the record into the DNS Record Explainer and it will break down each field for you.

48 hours out: drop your TTLs first

TTL (time to live) is the number of seconds resolvers may cache your answer. If app.example.com has a TTL of 86400 (one day), some users will keep hitting the old IP for up to a day after you change the record. That is the single most common cutover mistake: flipping the record while the old TTL is still baked into caches worldwide.

So the first move happens before the migration, not during it. At least one full old-TTL period ahead of the cutover window — 48 hours is comfortable for a one-day TTL — lower the TTL on every record you plan to change. I go to 300 seconds (5 minutes). Going lower buys little: several large resolvers enforce a floor, and 60-second TTLs multiply query load on your authoritative servers for marginal gain.

Also know the ceiling on the other side: Google Public DNS caps any TTL at 6 hours (21600 seconds) regardless of what your zone says, per Google's Public DNS documentation. So even a misconfigured week-long TTL clears through 8.8.8.8 within 6 hours — but you should never be relying on resolver caps to save a cutover.

Verify the drop took effect at the authoritative server, not just in your zone editor:

$ dig +noall +answer A app.example.com @ns1.example-dns.com
app.example.com.    300    IN    A    203.0.113.10

That 300 in the second column is the TTL. If it still reads 86400, your change has not published.

Pick the right record for the new target: A, AAAA, CNAME, or ALIAS

What you write at cutover time depends on what the new platform hands you.

  • A / AAAA — the platform gives you stable IPs. Write an A record for the IPv4 address and an AAAA for the IPv6 one. Publish both; a v6-only mobile client that finds no AAAA takes a slower NAT64 path or fails, and dual-stack has been table stakes for years.
  • CNAME — the platform gives you a hostname like lb-4821.provider.net. A CNAME aliases your name to theirs, so when the provider rotates IPs behind that hostname, you inherit the change without touching your zone. Use it for www and any other subdomain.
  • ALIAS / ANAME / flattened CNAME — the apex (example.com itself) cannot carry a standard CNAME, because the apex must also hold SOA and NS records and the spec forbids a CNAME from coexisting with them. Providers work around this with ALIAS-type records that resolve the target on their side and answer with plain A/AAAA. If you run your zone on Cloudflare, its CNAME flattening does this automatically — the Cloudflare DNS Cheatsheet covers the exact settings.
  • TXT — not part of the traffic path, but migrations regularly require one: platform domain-verification strings, and updated SPF if the new infrastructure sends mail. Add these before the flip so verification is already green when traffic arrives.

One trap worth calling out: a CNAME redirects every lookup for that name, including MX and TXT. If you CNAME your apex the "clever" way on a provider that allows it, your mail records vanish from resolution. That is exactly the class of mistake a record-by-record review catches.

The flip: change, verify, and watch both origins

During the cutover window, the checklist is short and strict:

  1. Confirm the new origin serves the site on its own hostname or IP (curl it directly — the curl Cheatsheet has the --resolve trick for testing a hostname against a specific IP before DNS changes).
  2. Change the records in one batch: A, AAAA, CNAME/ALIAS together.
  3. Verify at the authoritative server, then at public resolvers:
$ dig +short A app.example.com @ns1.example-dns.com
198.51.100.7

$ dig +short A app.example.com @1.1.1.1
198.51.100.7

$ dig +short A app.example.com @8.8.8.8
203.0.113.10

That output is a healthy mid-cutover state: the authoritative server and Cloudflare's resolver already return the new IP 198.51.100.7, while Google's resolver still serves the cached 203.0.113.10. Because you dropped the TTL to 300 earlier, that stale answer expires within five minutes. Re-run the @8.8.8.8 query and watch the TTL count down toward zero, then flip to the new address.

  1. Keep the old origin running and serving correctly for at least 24 hours. Zero downtime comes from both origins being valid simultaneously, not from DNS switching instantly — it never does.

When I migrated Toolora's own site to its current VPS, the step that saved me was number 4. I had dropped TTLs two days early and the flip itself was clean, but the old server's access log still showed a thin trickle of requests 9 hours after the change — stragglers behind corporate resolvers that ignore short TTLs. Because the old origin was still up and serving 200s rather than a connection refused, those users never noticed anything. I checked responses on both origins with curl -I during that window and watched the status codes; anything other than a 200 or an expected redirect would have been the early-warning signal (the HTTP Status Code Reference is the quick lookup when a proxy starts returning something exotic).

Propagation is not a mystery, and rollback is just another flip

"DNS propagation takes 24–48 hours" is folklore from the era of day-long TTLs. Nothing pushes DNS to resolvers; they simply re-query when their cached copy expires. With a 300-second TTL, the overwhelming majority of clients see the new record within minutes. The long tail is a small population of resolvers and OS-level caches that hold answers longer than they should — which is why you keep the old origin alive for a day, and why enterprise-heavy audiences deserve a longer overlap.

Rollback follows the same physics. Because your TTLs are still at 300, reverting is one record change plus a five-minute wait — no worse than the cutover itself. That is the real payoff of the TTL prep: it makes your undo fast, not just your do. Only after the migration has soaked for a few quiet days do I raise TTLs back to 3600 or higher to cut resolver load.

The whole checklist compresses to one sentence: lower TTLs early, publish the right record types for the new target, verify with dig against both authoritative and public resolvers, and keep both origins alive through the overlap. Every zero-downtime migration I have done was boring, and boring was the point.


Made by Toolora · Updated 2026-07-02