Planning DNS Rollback Windows Around TTL
Problem Statement
“We can always roll back the DNS” is true only for as long as the revert is cheap, and the price rises the moment you restore the original TTL or let a long-TTL record propagate. A rollback decision taken at hour three costs minutes; the same decision at hour thirty, after TTLs have been restored, costs hours during which half your visitors are on one stack and half on the other. Sizing that window in advance is what turns rollback from a hope into a plan. This page sits under DNS Rollback Procedures.
When to Use This Approach
- You are scheduling a DNS cutover and need to state, in the runbook, how long a cheap revert remains available.
- Stakeholders are asking for a “point of no return” and you need to give a defensible one.
- The record being changed has a long historical TTL that has not yet been lowered.
- You need to decide when to restore TTLs after a successful move without closing the window too early.
Rollback Is a Budget, Not a Button
The useful framing is that a cutover spends a budget of reversibility. At the start you hold the whole budget: nothing has changed, and undoing the change costs nothing. Every subsequent event spends some of it — the DNS change spends a little, the first write to the new database spends a lot, restoring the TTL spends what is left of the cheap portion.
Framing it this way makes two things obvious that a “point of no return” framing hides. The first is that the budget is spent by actions, not by time, so most of the schedule is under your control. Restoring TTLs early spends budget for no benefit; delaying the first write to the new stack preserves it. The second is that different parts of the system spend it at different rates, so there is no single moment when rollback becomes impossible — there is a sequence of moments at which particular rollbacks become expensive.
What the runbook needs, then, is not one deadline but a small table: which rollbacks are available, what each currently costs, and which event will change that. The on-call engineer reads it at 03:00 and gets an answer rather than a discussion.
# The two numbers the table depends on, both cheap to check at any moment
dig +noall +answer example.com A | awk '{print "record TTL:", $2}'
psql -h new-db.internal -Atc "select count(*) from orders where created_at > now() - interval '6 hours';"
Step-by-Step Instructions
1. Compute the Real Revert Time, Not the Nominal TTL
The worst-case time for a change to reach every resolver is the TTL as served plus the time since the record was last fetched, and some resolvers round or clamp the value. Plan against a multiple of the TTL, not the TTL itself.
# What TTL is actually being served, and what are resolvers currently holding?
dig +noall +answer @ns1.example.net example.com A # authoritative TTL
for r in 1.1.1.1 8.8.8.8 9.9.9.9 208.67.222.222; do
printf '%-16s ' "$r"; dig +noall +answer @"$r" example.com A | awk '{print $2, $5}'
done
The second command shows the remaining lifetime each resolver is counting down. A value close to the full TTL means that resolver has just refetched and will hold the answer for nearly the whole period.
2. Account for Negative Caching Too
If the rollback involves removing a record rather than repointing one, the relevant number is the zone’s SOA minimum — negative answers are cached under that value, and it is frequently far longer than the record TTL anybody lowered.
# The last field of the SOA is the negative-caching TTL; lower it with the others
dig +noall +answer example.com SOA
3. Write the Window Into the Runbook as a Clock Time
Convert the calculation into wall-clock times the on-call team can read at 3 a.m. without doing arithmetic: cheap window until 07:00, elevated cost until the TTL restore, and the restore itself scheduled explicitly.
4. Track the Point Where Data, Not DNS, Becomes the Constraint
Once the new stack has accepted writes — orders, accounts, uploads — reverting DNS sends users back to a system missing that data. That crossover, not the TTL, is usually the true point of no return, and it should be measured rather than assumed.
# Simple gauge: rows created on the new stack since cutover
psql -h new-db.internal -Atc \
"select count(*) from orders where created_at > timestamptz '2026-08-02 02:00Z';"
5. Restore TTLs Deliberately, and Late
Restoring TTLs ends the cheap window. Do it once the migration is demonstrably stable — not on the morning after, and following the sequence in Restoring DNS TTL After a Successful Cutover.
Worked Example
A payments integrator planned a Saturday 02:00 cutover with a 300-second TTL lowered 48 hours in advance. The runbook originally said “rollback available for 24 hours”, which was wrong in both directions.
Working the numbers changed the plan:
| Input | Value | Effect on revert |
|---|---|---|
| A record TTL | 300 s | ~10 minutes to full propagation |
| SOA minimum | 3600 s | irrelevant — no record removal planned |
| Resolver floor | up to 300 s | already covered by the TTL |
| First write on new stack | 02:14 | reconciliation needed after this |
The revised runbook said: DNS-only rollback until 02:14, costing about ten minutes; after that a rollback also required replaying writes from the new database, so the decision needed the data owner on the call. TTL restore was scheduled for the following Wednesday rather than Sunday, keeping the cheap DNS window open through the first full business week.
That week produced one incident — a TLS chain fault on a secondary hostname — and the ten-minute revert path was never needed, but the fact that it existed and was costed is what let the team fix forward calmly instead of arguing about whether rollback was still possible.
Verification
# 1. Every record in the cutover set is actually at the low TTL — check them all
for rec in example.com www.example.com api.example.com; do
printf '%-22s ' "$rec"; dig +noall +answer "$rec" | awk '{print $2}' | head -1
done
# 2. The SOA minimum is lowered too, if any record will be removed
dig +noall +answer example.com SOA | awk '{print "negative-cache TTL:", $NF}'
# 3. Time a simulated revert on a staging name to prove the window empirically
dig +short staging-canary.example.com # flip it, then poll until every resolver agrees
Check one catches the most common planning error: lowering the TTL on the apex and forgetting www or an API hostname, so one name reverts in a minute and another takes an hour. The multi-resolver polling technique is covered in Monitoring Global DNS Propagation During Cutover.
FAQ
How long before the cutover should I lower TTLs? At least twice the current TTL, so every resolver has had a chance to refetch at the lower value. Lowering a 24-hour TTL two hours before the change achieves nothing for resolvers that fetched the old value yesterday.
Does lowering the TTL hurt performance? Marginally and briefly. More frequent lookups add a few milliseconds on cache misses and slightly more load on the authoritative servers. For the days around a cutover that is a good trade for a fast revert; it is not a permanent setting.
Why does my revert take longer than the TTL? Because some resolvers apply a minimum lifetime of their own, some prefetch on their own schedule, and some clients hold their own cache below the resolver — browsers and JVMs are notable examples. Plan for a multiple of the TTL rather than the exact value.
Should I restore TTLs the day after a successful cutover? No. Restoring TTLs closes the cheap rollback window, and the problems that trigger a rollback often surface on the first full business day rather than overnight. Restoring after a week of stability costs nothing and keeps the option open through the risky period.
What if the rollback involves deleting a record rather than changing one? Then the SOA minimum governs how long the absence is cached, and that value is often untouched at an hour or more. Lower it along with the record TTLs, or design the rollback to repoint records rather than remove them.
Should the rollback window be the same for every record? It should be at least as long as the slowest record in the cutover set, because a rollback is only complete when every name has reverted. In practice that means lowering every record you will touch to the same value, so the window is one number rather than a set of them.
Does using a CDN in front of the origin change the calculation? It usually shortens it, because the record visitors resolve points at the edge and does not change during an origin swap — the switch happens in the CDN’s origin configuration, which propagates in seconds. That is a strong architectural argument for putting the edge in front before the migration rather than during it.
How does a weighted or gradual traffic shift interact with the window? It replaces a single cliff with a dial, and the dial is faster to turn back than DNS is to propagate. It does not remove the data problem — writes still accumulate on the new stack — but it does mean the traffic side of a rollback is near-instant.
Can I keep the low TTL permanently and avoid the whole question? You can, and some teams do. The cost is a modest increase in query volume and a few milliseconds on cache misses; the benefit is that every future change is cheaply reversible. For an estate that changes often, that trade is defensible.
What should the runbook actually say about the window? Wall-clock times and an owner, not a formula. “DNS-only rollback until 02:14, called by the on-call SRE; after that the data owner must join the call” is something a tired person can act on. A TTL calculation is not.
Related
← Back to DNS Rollback Procedures