aigw
← Back

The TTL guide nobody publishes

What TTL controls, what it doesn't, and how to pick a real value per record type.

Every DNS console makes you set a TTL. Most defaults are wrong. The few articles that exist online say "lower is more flexible, higher is more efficient" and stop there, which is true and useless.

Here's what TTL actually controls and how to pick a value you won't regret in an incident.

What TTL is

The TTL on a DNS record is the authoritative server saying to recursive resolvers: "you may cache this answer for at most N seconds". After N seconds, the resolver is supposed to re-ask the authoritative.

Three words doing heavy lifting in that sentence: "supposed to". TTL is advisory. Recursive resolvers can ignore it (and many do, both lower and higher), browsers and OS-level caches have their own clocks, and long-lived TCP connections bypass DNS entirely once established.

See Why your DNS failover failed for the full layered-cache picture. TL;DR: TTL is the floor on how often new answers propagate, not the ceiling.

What you're trading off

Short TTL means:

Long TTL means:

What to set, per record type

Apex A / AAAA for "the main site"

300s (5 min) is the right answer for most sites. Short enough that a planned cutover happens within a coffee break, long enough that resolver-cache savings still apply.

60s is fine if you really expect to need fast changes. Lower than 60 is mostly cargo-culting, resolver minimum-TTL floors kick in and you don't get the propagation benefit you think you're paying for.

Apex A / AAAA behind a CDN

Whatever the CDN docs say. If your DNS is pointing at a CDN's CNAME / anycast IP and the CDN handles failover at the network layer, your DNS TTL can be longer (3600s / 1h). Changing the record means changing CDN providers, which is a planned activity you'll handle days in advance anyway.

www CNAME pointing at the apex

Match the apex TTL or go longer. The www → apex CNAME basically never changes; setting it to 300s buys you nothing and just makes resolvers re-fetch needlessly.

MX records

3600s (1h) to 86400s (24h). MX changes are rare, you set them when you sign up for Google Workspace or M365, and that's it for years. A long TTL means SMTP retries don't hammer your authoritative for no reason.

TXT for SPF, DKIM, DMARC

3600s. Email systems are designed to handle these caching for a while. Anti-spam infrastructure will refetch on its own schedule. 60s here is pointless.

Verification TXTs (Google Search Console, Stripe, etc.)

60–300s while you're verifying, then delete the record if the vendor allows. Some vendors check once and never again. Some check every 24h to confirm you still own the domain. Leave the TXT in place if unsure, but a long TTL is fine.

NS at the apex

86400s (1 day) under normal operation, 300s when migrating. The apex NS TTL is what controls how fast a "we're switching DNS providers" change propagates. Lower it 2 days before the planned migration; reset to 1 day after.

Active failover A records

30–60s. The whole point of these records is to change quickly. Short TTL is the cost of admission. Be aware that resolver minimum-TTL floors and browser caches will still slow propagation regardless, DNS failover is a 5-minute thing in practice, not a 30-second thing.

Static-asset records (assets.example.com pointing at S3 / CDN)

3600s or longer. These targets don't change. Long TTL means resolvers cache the answer and page-load latency drops for repeat visitors.

A common mistake

"Set everything to 60 because I want flexibility." This sounds prudent and is usually wrong. It increases your DNS bill (or your authoritative-server load), increases cache misses, and gives you flexibility you'll never use for records that change once a decade. The MX record for hello@yourdomain hasn't changed since 2017. It doesn't need a 60-second TTL.

Use 60–300 only for records you actually expect to change. Set everything else to 3600+ and forget about it.

A practical default-set

How aigw handles it

aigw lets you set a per-zone default TTL (we suggest 300s for new zones) and override per record. The Test Query button on every record shows the current TTL value resolvers will see, so you can verify before pushing changes.

For zones with many records, the Terraform provider supports a default-TTL variable so you can stop copy-pasting ttl = 300 into every resource block.

See also: Why your DNS failover failed, EDNS Client Subnet doesn't do what you think it does.