DEV Community

Leonardo Bagno
Leonardo Bagno

Posted on

Lowering your DNS TTL will not speed up your failover, and here is the data showing why

I spent three months measuring multi-cloud DNS failover for my final-year dissertation. The most useful thing I learned contradicts common advice, so I'm sharing the numbers.

The assumption

When the AWS US-East-1 outage hit in October 2025, half the internet went down with it. The standard answer to "how do I survive a cloud outage?" is DNS-based failover: run a standby in another cloud, point a Route 53 health check at your primary, and let DNS redirect traffic when it fails.

And the standard tuning advice that comes with it: lower your TTL to fail over faster. Set it to 60 seconds instead of 300 and you'll recover five times quicker. It sounds obvious. It's also wrong. Or at least, it's only a small part of the story.

The experiment

I built a deliberately minimal setup so the measurements would be clean:

  • A stateless Flask weather app deployed identically on AWS EC2 (eu-west-1) and an Azure VM (northeurope), via Terraform
  • Route 53 with failover routing and a health check on the primary
  • No Docker, no orchestration. I removed anything that added boot-time noise to the measurements

Then I killed the primary. Nine times, across three TTL configurations (60s, 120s, 300s), measuring from multiple DNS resolvers, plus three failback runs in the other direction. Every run logged to CSV.

The finding

Failover time (RTO) has two separate components, and most advice mixes them up:

1. Detection time: how long Route 53 takes to notice your primary is dead. In my runs this came out at ~48 seconds, and here's the key part: it was constant across every TTL configuration. TTL=60 and TTL=300 detected the failure in the same time, because detection is governed by Route 53's internal polling and quorum logic, not by the TTL advertised to resolvers. To reduce it, you need to adjust the health check interval and the failure threshold.

2. Propagation time: how long resolvers take to pick up the new record. This is where TTL matters, but it turned out to be resolver-dependent, and sometimes dramatically so. The clearest example: at TTL=300s, Cloudflare's resolver kept oscillating for over 325 seconds after the failover, while Google DNS stabilised much faster. Same record, same TTL, very different behaviour depending on who resolves your users' queries.

The full numbers:

Metric Result
Mean failover RTO (all TTL configs, n=9) 48.0 s
RTO at TTL=60s (mean ± SD) 46.3 s ± 0.6 s
RTO at TTL=120s (mean ± SD) 45.3 s ± 2.9 s
RTO at TTL=300s (mean ± SD) 52.3 s ± 7.6 s
Failback RTO at TTL=60s (mean ± SD) 35.3 s ± 3.1 s
Route 53 detection time ~48 s, TTL-independent
RPO 0 s (stateless workload)
Total infrastructure cost < €5 across all three iterations

Notice the pattern: TTL=60 and TTL=120 land within noise of each other, because detection dominates both. Only at TTL=300 does the RTO climb, and its standard deviation more than doubles, because now you're at the mercy of resolver caching. RPO was zero, but only because the app was stateless. A real application with a database would not get the same result.

Why this matters

If your failover is taking 60+ seconds and you respond by dropping the TTL from 300 to 60, you'll be disappointed. You're optimising the small, variable component while the large, constant one (health check detection) stays exactly where it was.

The practical order of operations is the opposite of the common advice:

  1. Tune the health check first. Interval and failure threshold set the floor for your RTO. This is the big lever.
  2. Then lower the TTL. It helps with the tail, not the floor.
  3. And don't trust the TTL blindly, because resolvers between you and your users have opinions of their own.

Reproduce it for under €5

Everything is public and runs on free-tier-sized instances: the Terraform code, the measurement scripts, and the raw CSVs from every run.

Total cloud spend for the entire experimental campaign was under €5. If you want to verify my numbers or run the tests against a different DNS provider, terraform apply gets you there.

New findings coming soon

The stateless app made RPO trivially zero, which avoids the hardest part of real disaster recovery: data. So this project is not finished. I'm already working on the next iteration, and the numbers will land here and in the repo.

Stay tuned and follow the repo for more to come.

Top comments (0)