DEV Community

Aaroophan Varatharajan
Aaroophan Varatharajan

Posted on Originally published at aaroophan.Medium on

DNS Exists Because Nobody Can Know Every Name: Rethinking Distributed Computing #10

The first naming system is a table. The last thing that table wants to become is the Internet.

DNS solves the Internet’s naming problem through hierarchy, delegation, zones, caching, recursion, and TTLs, letting distributed systems scale without a single server knowing everything.
"DNS solves the Internet’s naming problem through hierarchy, delegation, zones, caching, recursion, and TTLs, letting distributed systems scale without a single server knowing everything."

Suppose we have a handful of computers.

Humans want names like:

  • Server1
  • Mail
  • Database

The network wants addresses.

So we make a table.

server1 → 192.0.2.10
mail → 192.0.2.20
database → 192.0.2.30
Enter fullscreen mode Exit fullscreen mode

✨Done✨

This is such a reasonable solution that the early Internet effectively did exactly this. Hostname-to-address mappings were maintained centrally in a file called HOSTS.TXT , which hosts periodically retrieved from the Network Information Center.

For a small network, this is beautiful.

One file.

One authority.

One answer.

Then the network grows.

Add another hundred machines.

Then another thousand.

Names change.

Addresses change.

Organizations want to administer their own machines.

Everyone needs a fresh copy of the table.

Suddenly our tiny lookup file has developed the administrative ambitions of a global database.

RFC 1034 describes the historical problem directly: as the Internet grew, maintaining and distributing the central HOSTS.TXT file became increasingly expensive, while organizations also wanted local control over their own names.

The table did not become bad.

The assumption hiding underneath it did.

One authority can know every name.

That assumption was about to stop scaling.


A Name Is Not an Address

Before fixing the table, there is a distinction worth making.

Humans like names: www.example.com

Networks communicate using addresses: 192.0.2.10

Those are different jobs.

A name tells us what entity we are talking about.

An address tells us where that entity can currently be reached.

If we bake location directly into identity, moving something becomes awkward.

Change the machine.

Change the network.

Change the address.

Now every reference to the old location potentially becomes wrong.

A naming system gives us indirection: name --> binding --> attribute

A binding associates a name with an object or one of its attributes.

An attribute might be an address.

But it does not have to be.

A host name can have attributes such as:

  • an IP address,
  • the type of entry,
  • how long the information remains valid.

And an identifier is stricter still: ideally, it refers unambiguously to one entity, is not reused, and does not drift between different objects.

Names help humans refer.

Identifiers distinguish entities.

Attributes describe them.

It sounds slightly pedantic until the entity moves.

Then the separation earns its keep.


The Lookup Is the Real Service

Once names are separate from attributes, we need something capable of maintaining those relationships.

That is a name service.

Conceptually it stores bindings such as: (name, attribute)

and performs name resolution :

Given this name, what attribute belongs to it?

A telephone directory is a familiar version.

Given a person’s name, find a telephone number.

DNS performs another:

Given a domain name, find information such as an IP address.

Peer-to-peer discovery asks a variation:

Given the thing I want, where can I find it?

Service discovery asks:

Given the service name, which endpoint implements it?

Different systems.

Same underlying problem.

Names are useful only if something can resolve them.

And once enough applications depend on resolution, the naming service quietly becomes critical infrastructure.

Which brings us right back to our first mistake.

Where should that information live?


The Central Directory Is Seductive for a Reason

The easiest answer is still:

Put all the bindings in one place.

A centralized name server is wonderfully simple.

Clients know where to ask.

Updates go to one authority.

There is one obvious source of truth.

Resolution is straightforward: clients --> name server --> answer

If the server contains: foo.example --> 203.0.113.7

the problem is finished in one lookup.

This design should feel attractive because it is attractive.

Centralization removes uncertainty.

No referrals.

No distributed ownership.

No guessing which server knows what.

But growth starts charging interest.

The database becomes larger.

The query load becomes larger.

Updates from independent organizations all converge on one administrative boundary.

That machine becomes a bottleneck.

It becomes a failure dependency.

And perhaps most importantly, every organization has to ask someone else to manage names that logically belong to itself.

The lookup problem has become an authority problem.

The system needs to scale not only query traffic, but ownership.


A Namespace Gives the Names Somewhere to Live

The next idea is structure.

Instead of treating every valid name as an unrelated string in one enormous table, organize names into a namespace.

A namespace is the collection of valid names recognized by a service.

It can be represented as a graph.

There are directory nodes , which contain outgoing edges.

And leaf nodes , which represent named entities.

A pathname gives us a familiar version:

/
└── users
    └── alice
        └── report
Enter fullscreen mode Exit fullscreen mode

The structure matters because a name can now describe a path through smaller naming contexts.

Instead of every authority managing one giant flat list, different parts of the graph can potentially be managed separately.

This is where hierarchy stops being cosmetic.

It creates boundaries.

And boundaries give us somewhere to place authority.


A Directory Service Asks a Different Question

There is another useful distinction before DNS takes over the story.

A name service commonly starts with a name and returns attributes:

What is associated with alice.example ?

A directory service can work more like yellow pages.

Instead of knowing the exact name, we may search by attributes.

For example:

Which user has telephone number 2729729 ?

Or:

Which hosts are running Linux Kernel version 3.1?

Now the query is not merely: name --> attributes

It can be closer to: attributes --> matching objects

Systems such as LDAP and Active Directory live comfortably in this world.

The distinction matters because distributed naming is not merely about giving everything a memorable label.

Sometimes the system knows what properties it needs before it knows which object satisfies them.

But whichever direction we search, scale still asks the same uncomfortable question:

Who is expected to maintain all this knowledge?


There Are Several Ways to Find an Answer, and They All Send the Bill Somewhere

Suppose we need to resolve a name.

There are several broad approaches.

  • Centralized: ask one authority. Simple, until that authority becomes the bottleneck.
  • Broadcast: ask everybody. No central directory required, but everybody gets involved.
  • Gossiping: let information propagate through participants. Useful in some distributed environments, but convergence and lookup behaviour become different problems.
  • Distributed: divide the knowledge among several machines. Now we need to know which machine has the relevant knowledge.

And hierarchical resolution gives us a particularly useful compromise:

Nobody knows everything, but somebody knows who knows more.

That turns out to be the trick.

The system does not need one omniscient server.

It needs a chain of increasingly specific authority.


DNS Makes Ignorance Part of the Design

The Domain Name System organizes the namespace hierarchically.

Consider: www.example.com

Read conceptually from the broadest authority toward the most specific:

.
└── com
    └── example
        └── www
Enter fullscreen mode Exit fullscreen mode

At the top is the root.

Below it are domains such as .com.

Below those are organizations and subdomains.

The important part is not the dots.

The important part is delegation.

A root name server does not need to know the IP address of every www host on Earth.

It needs enough information to say:

I don’t own the answer for www.example.com , but I know who is responsible for _ **.com_** .

The .com authority does not need to know everything under every organization either.

It can say:

Ask the name servers responsible for example.com .

Eventually the query reaches the authority that actually owns the relevant data.

RFC 1034 describes DNS as a distributed database divided into zones. Individual name servers are authoritative for only parts of the domain tree and can return either an answer from their local knowledge or a referral toward another server closer to the requested information.

This is the architectural breakthrough:

A server is allowed not to know the answer.

It just needs to know where the responsibility continues.


Zones Turn Hierarchy Into Administrative Ownership

The DNS namespace is a logical tree.

Administration does not require one server to own an entire branch forever.

Instead, the database is partitioned into zones.

A zone contains authoritative information for some connected portion of the namespace.

At a boundary, responsibility can be delegated to another zone.

Imagine:

.
└── com
    └── example.com
        ├── www
        ├── mail
        └── research
Enter fullscreen mode Exit fullscreen mode

The authority responsible for .com does not administer every record inside example.com.

Responsibility is delegated.

The organization controlling example.com can manage its own records.

It can even delegate: research.example.com to another authority.

This solves more than technical scaling.

It solves organizational scaling.

The Internet is not one administration.

It is thousands of independent administrations.

DNS works because its technical hierarchy can follow those ownership boundaries.

RFC 1034 explicitly notes that zone boundaries can be created where an organization wants to take control of a subtree, after which it can modify that area and delegate further subzones.

Nobody has to maintain the entire database.

Each authority maintains the part it owns.

The tree connects those independent authorities into one namespace.


Iterative Resolution Says, “Not Me, Try Them”

Now the client wants: www.example.com

One style of resolution is iterative.

The resolver asks a name server.

The server may respond:

I don’t know the final answer, but ask this server next.

So resolution progresses through referrals.

Conceptually:

Resolver → Root
Root → Ask .com

Resolver → .com
.com → Ask example.com

Resolver → example.com
example → Here is the answer
Enter fullscreen mode Exit fullscreen mode

Nobody performed the entire lookup on behalf of the resolver.

Each authority answered only from what it knew.

Often that answer was not:

Here is the IP address.

It was:

Here is the next authority.

This is distributed knowledge working exactly as intended.

Ignorance is not failure.

Unstructured ignorance would be failure.

DNS gives ignorance a route.


Recursive Resolution Says, “I’ll Handle the Chase”

There is another model.

The client asks one server:

Resolve this name for me.

That server then performs the remaining work.

It contacts other servers.

Follows referrals.

Finds the answer.

Returns the final result.

That is recursive resolution.

The difference is about who carries the responsibility for continuing the lookup.

With iteration:

Here is where you should ask next.

With recursion:

I’ll ask next for you.

Real DNS resolution often combines these behaviours. A host commonly sends a recursive request to a configured resolver, while that resolver performs the necessary queries toward authoritative DNS infrastructure.

RFC 1035 describes the resolver as the component responsible for hiding the distribution of DNS data from the user; it may query several foreign name servers before it can answer a single client request.

The user still experiences: resolve("www.example.com")

Underneath it may be a small distributed expedition through several administrative boundaries.

That is transparency doing useful work.


Then We Realize We Are Asking the Same Questions Repeatedly

Hierarchical resolution scales authority.

But a single lookup may require several network requests.

And humans are terribly repetitive.

Many users ask for the same popular domains.

Again.

And again.

And again.

Making every lookup walk from the top of the hierarchy would be correct.

It would also be surprisingly wasteful.

So DNS uses caching.

A resolver learns: www.example.com --> 203.0.113.20 and keeps the result locally.

The next client asking for the same information can receive the cached answer without repeating the entire distributed lookup.

Now the hierarchy handles the hard lookup once.

The cache handles repeated demand nearby.

Performance improves.

Network traffic falls.

Authoritative servers receive fewer repeated queries.

Lovely.

We have also created copies of naming information.

Which means we have created the possibility that those copies become stale.

Distributed systems really do have recurring hobbies.


TTL Is the Cache Admitting It Cannot Know Forever

Suppose www.example.com changes address.

The authoritative DNS data is updated.

Some resolver elsewhere still has the old answer cached.

Which answer does the next client receive?

Immediately forcing every cached copy on Earth to update would require precisely the sort of global synchronization DNS was designed to avoid.

So cached DNS data has a Time To Live , or TTL.

A DNS resource record carries a value specifying how long it may be cached before the original information should be consulted again.

RFC 1035 defines TTL specifically as the interval for which a resource record may remain cached; cached data improves repeated retrieval performance, but it is eventually discarded as its lifetime expires.

This creates an explicit trade-off.

Long TTL:

  • fewer DNS queries,
  • better cache effectiveness,
  • slower propagation of changes.

Short TTL:

  • fresher answers,
  • more frequent authoritative lookups,
  • more network and server load.

There is no universally perfect number because the source of the data knows something the cache does not:

How quickly is this information expected to change?

So DNS lets the authority influence that trade-off.

The cache is useful precisely because it is allowed to temporarily know something without continuously asking whether it is still true.

TTL stops that confidence from becoming permanent.


Authoritative and Cached Are Different Kinds of Knowledge

This distinction is deeper than it first appears.

An authoritative name server owns information for its zone.

It can say:

According to the authority responsible for this namespace, this is the record.

A recursive resolver may also know the answer.

But perhaps only because it learned the answer earlier and cached it.

That is non-authoritative knowledge.

Both can be useful.

They do not have equal ownership.

The resolver is remembering.

The authoritative server is responsible.

RFC 1034 explicitly distinguishes authoritative zone data from cached information a name server may have learned about other parts of the tree.

That separation lets DNS scale without pretending all copies are equivalent.

A cache can answer quickly.

Authority remains somewhere else.

When the cache’s confidence expires, it goes back toward authority.

This is distributed state with a refresh policy instead of distributed state pretending it never gets old.


The Name Can Even Stop Pointing to One Place

Once names are separated from physical location, another interesting possibility appears.

Suppose a website has replicated content across multiple servers.

Now resolving the name does not necessarily mean:

Find the one permanent machine where this website lives.

The naming layer can participate in choosing which replica should serve the request.

This is useful for Content Delivery Networks.

Copies of content can be placed closer to users at network edges.

DNS-based selection can direct requests toward an appropriate replica by controlling which address is returned for a name.

The naming system has evolved from a telephone book into part of the traffic-steering mechanism.

That is powerful.

It also exposes another trade-off.

DNS caching is one of the reasons naming-based selection is efficient.

But cached answers mean the selection decision cannot necessarily be changed independently for every request.

And a DNS resolver may be making the query on behalf of the actual client, so the DNS infrastructure may see the resolver’s location rather than the client’s exact location.

Again: the abstraction buys us something.

And again: the abstraction has constraints.

The same caching that makes name resolution scale can make perfectly fine-grained traffic steering harder.


Nobody Knows Everything, and That Is Why It Works

Return to our first table: name --> address

There was nothing wrong with it.

The table worked because the world around it was small enough for one authority to maintain the whole thing.

Then the number of names increased.

Updates increased.

Administrative boundaries multiplied.

Traffic increased.

One database became expensive to distribute.

One owner became awkward.

One server became dangerous.

So The Origami Software Engineer changed the design.

Names were organized into a namespace.

The namespace became hierarchical.

Hierarchy created boundaries.

Boundaries enabled delegation.

Delegation distributed authority.

Zones gave each authority a manageable portion of the database.

Resolvers followed referrals between those authorities.

Caching prevented every repeated lookup from traversing the whole structure.

TTL acknowledged that cached knowledge ages.

And the same indirection eventually became useful for choosing among replicated services.

The system never found a server powerful enough to know every name.

It found something better:

A way for servers to know only the names they are responsible for, while still helping a client find any name in the larger system.

That is the part worth keeping.

Scalable distributed systems are often not built by giving every component more knowledge.

They are built by deciding who is authoritative for what , giving everyone enough structure to find that authority, and allowing temporary local knowledge where it reduces unnecessary work.

DNS succeeds because no machine has to understand the entire Internet.

It only has to know its part of the truth or where to ask next.

That’s not failure.

That’s evolution.


The “I liked this” Starter Pack:

Don’t let your fingers get lazy now.

  • Like : It tells me this was worth writing.
  • A Comment: Tell me your thoughts, your favorite snack, or a better title for this blog.
  • Boost it: Especially with that one developer who definitely needs this.

Thanks for being here. It genuinely helps more than you know!

— Aaroophan Varatharajan

Find me elsewhere:

Top comments (0)