The Case for Boring DNS Records

DNS rewards restraint. A short record can sit underneath browsers, certificates, service discovery, remote access, and every note that tells someone where to go. Because the syntax is compact, it's tempting to use records as a clever abstraction layer. Then a troubleshooting session becomes a tou...

a desk with a lamp and a laptop on it

DNS rewards restraint. A short record can sit underneath browsers, certificates, service discovery, remote access, and every note that tells someone where to go. Because the syntax is compact, it's tempting to use records as a clever abstraction layer. Then a troubleshooting session becomes a tour through aliases that were individually reasonable and collectively mysterious.

I prefer records that make ownership and destination unsurprising. That usually means stable names for stable roles, shallow alias chains, deliberate internal and external views, and time-to-live values chosen for actual change behavior. Boring DNS doesn't mean primitive DNS. It means a lookup result should be easier to explain than the service it names.

Myth: names are just friendly addresses

A DNS name often becomes a service identity. Certificates refer to it. Browser security rules distinguish it. Configuration files store it. People bookmark it. Changing the name can therefore change more than the address a client receives.

This is why I name roles instead of temporary machines. A service name can continue to point at a replacement host without teaching every caller the new machine identity. The record stays stable while the implementation moves behind it.

The reverse is also true: a machine name shouldn't quietly become the permanent public identity of several services just because it was available during setup. That coupling makes later separation harder. The convenient name has accumulated promises no DNS editor will display.

I keep the record's purpose narrow and write down who is allowed to change its destination. The name may be easy to edit, but the systems trusting it make that edit an operational change.

Myth: another alias always makes migration easier

Aliases are useful. They let one name follow another and can reduce repeated address changes. The trouble starts when aliases form a chain across different owners or purposes.

Each hop adds another cache lifetime, another record that can be removed, and another place where an internal and external answer may diverge. Clients also have protocol-specific rules about which record types can appear at certain names. A design that works for one hostname isn't automatically a universal indirection scheme.

My default is one understandable alias at most between a user-facing name and the authoritative destination. If a second alias is proposed, I ask what independent change it enables. “It might help later” isn't enough. Future flexibility that nobody owns is present-day ambiguity.

During a move, I query the full answer from the resolver path the client uses and inspect every hop. After the move, I remove migration-only indirection once caches and dependent configuration have had time to settle. Temporary aliases are remarkably skilled at earning tenure.

Myth: split DNS should hide every network difference

Returning different answers inside and outside a network can be the cleanest way to keep traffic on an appropriate path. It can also create two realities under one name. That is manageable when the difference is deliberate, documented, and tested from both sides.

It becomes confusing when internal answers are added as patches for routing or certificate problems. A laptop works on one connection and fails on another. A mobile device retains an answer while changing networks. The service team sees a valid public record, while the client is still using an internal result. None of this is exotic; it is caching combined with two authorities.

I use split views only where the service identity remains the same and the different destinations are both supported paths. I don't use them to make an internal-only service look public or to conceal that two environments have different behavior. The record should route a known distinction, not erase one from the documentation.

Testing has to include a normal client on each relevant side. Querying the authoritative server directly can prove the record exists while skipping the recursive resolver and cache the client actually trusts.

Myth: a low TTL makes change safe

A low time-to-live can shorten how long compliant caches retain an old answer. It can't make a bad destination good, update an already established connection, or guarantee that every application refreshes on schedule. Lowering it immediately before a change may also be too late if resolvers already cached the previous, longer value.

I choose TTLs as part of the operating rhythm. Stable records can tolerate longer caching. A planned migration may justify lowering the value in advance, waiting out the former lifetime, making the change, and restoring a normal value after the destination is settled. Keeping everything permanently low trades some cache efficiency for an illusion of constant agility.

Rollback needs the same preparation as the forward change. The prior destination should remain capable of serving the name for as long as old answers may be in use. If it can't, the migration isn't made safe by asking caches to hurry.

The boring operating rule is to know the old answer, new answer, relevant cache lifetimes, and client paths before editing the record. Afterward, I check the name through those client resolvers and confirm the application still accepts that identity. I don't declare success because one direct query returned the value I just typed.

DNS is small enough to invite casual changes and central enough to punish them. I keep names stable, alias chains shallow, split views explicit, and TTLs tied to a plan. When a record needs a diagram to explain why it reaches a service, I haven't made the network flexible. I've made a tiny database tell a story it can't maintain.