How to Lower DNS TTL Before Domain Migration

Problem Statement

A default TTL of 86400 s pins recursive resolvers to your legacy IP for up to a full day, so a cutover that flips the record cleanly at the source still leaves caches worldwide serving the old origin. That stretches the propagation window to 24-48 hours, produces split-brain routing, and — critically — makes rollback slow, because reverting the record is just as cache-bound as the original change. If a cutover goes wrong with an 86400 s TTL still in force, your “instant” revert is anything but: the caches that adopted the broken record will hold it for hours. Lowering TTL ahead of time shrinks both halves of the risk at once — the propagation tail going in, and the rollback window coming out. The subtlety is doing it without stressing secondary nameservers or tripping a registrar TTL floor that silently overrides your zone value. This page sits under TTL Optimization Strategies and covers the exact decay schedule, the commands for BIND and provider APIs, and how to confirm the lowered value is actually being served.

Progressive TTL decay schedule TTL steps down from 86400 to 3600 to 300 seconds over 72 hours, narrowing the cutover and rollback window before the swap. Progressive TTL Decay 86400 s 3600 s 300 s T-72h baseline T-48h step down T-2h cutover floor Rollback window = 300 s Each step lets old caches expire before the next
Stepping the TTL down in stages avoids zone-transfer stress while shrinking the cutover and rollback window to 300 seconds.

When to Use This Approach

  • You have a scheduled cutover and want the new record adopted globally in minutes, not days.
  • Current TTLs are high (3600 s or above) and would otherwise dominate the propagation tail.
  • You need a short rollback window so reverting a failed cutover takes minutes.
  • You manage A, AAAA, CNAME, and MX records that must all change in step (mail included).
  • You can publish changes 48-72 hours ahead, leaving time for the old long TTLs to expire first.

Step-by-Step Instructions

1. Baseline Every Record’s Current TTL

You cannot shrink a window you have not measured. Export the full zone and map each record’s current TTL, including the SOA MINIMUM that governs negative (NXDOMAIN) caching.

# Pull the full zone (or use the provider API export) and inspect TTLs
dig AXFR @ns1.provider.com domain.com   # lists every record with its TTL
dig SOA domain.com +noall +answer        # last field = MINIMUM (negative-cache TTL)

2. Apply Progressive TTL Decay

Step the TTL down 86400 -> 3600 -> 300 over 48-72 hours rather than dropping it in one move; this avoids secondary-nameserver rejection and follows the TTL Optimization Strategies decay model. The reason for the staircase is that a resolver caching the old 86400 s value will not see your new low value until that cache expires, so dropping straight to 300 s buys nothing until a day later anyway — stepping down lets each prior TTL age out before the next reduction lands. Bump the SOA serial on every change so secondaries pull the update, and confirm refresh/retry/expire values leave room for the transfer.

# nsupdate: transactional TTL reduction on an authoritative BIND server
nsupdate -v <<EOF
server ns1.provider.com
zone domain.com
update delete example.com. A
update add example.com. 300 A 203.0.113.5   # new low TTL, same IP for now
send
EOF

3. Track Records in a Reduction Sheet

Drive bulk updates from a CSV so every record’s old and new TTL is version-controlled and nothing is missed — MX records in particular are easy to overlook.

# TTL reduction tracking (mail included so deliverability is not broken)
record_type,hostname,current_ttl,new_ttl,ip_target,target_provider
A,www,86400,300,203.0.113.5,cloudflare
MX,@,3600,300,mx.provider.com,aws

4. Hold Caches Off at the Edge

Lowering DNS TTL does not control CDN edge caching, which obeys HTTP max-age. Set explicit no-cache headers on origin responses for the cutover window so the edge does not pin stale content independently of DNS.

# Origin response headers during the cutover window
Cache-Control: no-cache, no-store, must-revalidate   # edge must revalidate
Pragma: no-cache
Expires: 0

Not every record deserves the same treatment, and lowering everything uniformly multiplies authoritative query load for no extra agility. Weight the reduction by what each record type costs you if it is still stale at cutover.

Which record types to lower before a cutover A five-row table giving each record type a target TTL, the point in the schedule at which to lower it, and the failure that results from leaving it stale. Lower what the cutover changes — not the whole zone Record Target Lower at If left stale at cutover A / AAAA 300 s T−72 h, stepped split-brain routing for up to a day MX 300 s T−48 h mail bounces or defers, silently SOA MINIMUM 300 s T−48 h a brief gap is cached as NXDOMAIN CNAME 300 s with its target subdomain lags the apex TXT / NS leave alone NS is governed by the registry, not you
Only the records the cutover actually moves need the aggressive floor; `NS` delegation is cached at the parent zone on the registry's schedule regardless of what you publish.

Worked Example

A team migrating domain.com finds its A record at TTL 86400 s and its MX at 3600 s. Seventy-two hours before cutover they drop A to 3600 s; 48 hours out they drop both A and MX to 300 s. They verify the resolver is honouring the new value rather than a registrar floor:

dig @8.8.8.8 domain.com A +noall +answer
# domain.com.  300  IN  A  203.0.113.5   <- effective TTL is 300, not 86400

One resolver returns a TTL of 300 s but the registrar GUI shows a 600 s minimum on the apex; the team confirms via dig that the published 300 s is being served, so the registrar note was stale. They also catch that the NXDOMAIN negative-cache TTL, governed by the SOA MINIMUM field, was still set to 3600 s — meaning a momentary missing record during the swap would be cached as “does not exist” for an hour — and lower it to 300 s to match. At cutover they swap the IP, and because the tail is bounded at 300 s, global adoption (tracked in Monitoring Global DNS Propagation During Cutover) crosses 90% within 15 minutes instead of hours. When a 5xx spike appears on the new origin, they revert the record and recover in under 5 minutes — the short TTL pays off on the rollback path exactly when it matters most.

The negative-cache detail in that example is the one most teams meet only once, and always the hard way. Negative caching is governed by the SOA MINIMUM field rather than by any TTL on the record itself, and it applies to answers that do not exist yet — so a name queried in the moments before it is created gets its “does not exist” answer cached for the MINIMUM duration, regardless of how quickly you then create it.

Negative caching outliving the record it denies A probe queries a hostname before it exists, the resolver caches the NXDOMAIN for the SOA MINIMUM duration, and the record created moments later stays invisible to that resolver until the negative cache expires. A record can exist and still answer "no such name" Authoritative zone What one resolver serves api.domain.com exists — answers 203.0.113.5 NXDOMAIN cached for SOA MINIMUM finally correct a probe queried the name here, before it was created Lower SOA MINIMUM with the record TTLs, and never query a hostname before you have created it. The gap between the two lanes is entirely self-inflicted.
The record was published seconds after the probe ran, but that resolver kept denying it for the full `SOA MINIMUM` window.

Verification

Confirm the lowered TTL is actually being served, across resolvers and after a cache flush.

# 1. Compare returned TTL across several resolvers; all should read ~300
for r in 8.8.8.8 1.1.1.1 9.9.9.9; do dig @"$r" domain.com A +noall +answer; done
# 2. Flush local cache so you test the resolver, not your stub
sudo resolvectl flush-caches    # Windows: ipconfig /flushdns
# 3. Confirm the record still answers correctly end to end
curl -I -s -o /dev/null -w '%{http_code}\n' https://domain.com   # expect 200/301

FAQ

What is the minimum safe TTL before a domain migration cutover? Use 60-300 seconds, with 300 s as the most reliable floor for broad ISP compatibility. Values below 60 s can trigger resolver-enforced minimums or provider rate limits, which add latency without speeding propagation and can risk split-brain routing.

How do I verify if a resolver is ignoring my lowered TTL? Run dig @resolver domain.com +noall +answer and compare the returned TTL against your authoritative zone value. A consistently high returned TTL despite your lower setting indicates a stale cache, a resolver-enforced minimum, or a registrar TTL floor overriding you.

Does lowering TTL affect email deliverability during migration? Yes — MX record TTLs must be lowered on the same schedule as A records. If the mail server IP changes before resolvers adopt the new MX record, mail routing fails and you see deferred or bounced messages, so include MX in your reduction sheet. Mail failures are also slower to surface than web failures: a sending server that gets a stale answer will typically queue and retry for hours before generating a bounce, so the problem is often several hours old by the time anyone reports it.

What if I only remember to lower the TTL the day before? Lower it anyway, and plan the cutover around the old value rather than the new one. Publishing 300 s twenty-four hours before a cutover does not give you a 300-second tail — resolvers that cached the previous 86400 s value keep it until it expires, so a share of the population will still be operating on day-old data at cutover. What the late reduction does buy is a fast rollback, because by the time you would need to revert, most resolvers will have refreshed and picked up the short value. Treat it as insurance on the way out rather than speed on the way in.

Can I lower the TTL without touching the record value? Yes, and you should — that is exactly what the reduction phase is. Republishing a record with the same value and a lower TTL is a no-op for anyone resolving it and changes only how long the answer may be cached. It is worth confirming your provider treats it that way too: a few interfaces rebuild the record on save in a way that briefly removes and re-adds it, which is precisely the momentary gap that gets cached as an NXDOMAIN. Check by watching a resolver through the change on a low-value record before doing it on the apex.

Related

← Back to TTL Optimization Strategies