plcdns: Using Global DNS Cache for PLC Records

I was scrolling Nostr when I saw Tim Bouma's post about dnspub. The concept was beautifully simple: publish your Nostr profile info as DNS records. No http client needed — just DNS, baked into every operating system since forever:

My immediate thought: "This would be fun to try with AT Protocol".

Four hours later, I had a DNS server running. I called it plcdns .

@tree.fail/plcdns

PLC Directory over DNS

Why This Matters (Or Might Not)

Let's be honest: nobody needs this. You can get all this information with a simple HTTP request to plc.directory .

But here's the interesting part: DNS is cached everywhere. Your OS caches it. Your router caches it. Your ISP caches it. Cloudflare and Google cache it. When you query a domain, you're tapping into this massive, distributed caching network that already exists.

What if DID resolution could use that same infrastructure?

dig _handle.z72i7hdynmk6r22z27h6tvur.plc.atscan.net TXT

That query could be answered by your local DNS cache. Or your ISP's cache. Or Cloudflare's cache. Without ever hitting the PLC directory.

For a protocol that wants to be global and decentralized, plugging into the internet's oldest distributed database seems... interesting?

How DNS Caching Actually Works

DNS caching happens in layers:

Your computer (usually) caches DNS responses. Query the same domain twice, and the second one never leaves your machine. This is why running the same dig command twice feels instant.

Recursive resolvers (like 8.8.8.8 or 1.1.1.1) have massive caches serving millions of users. If one person looks up a DID, and someone else queries it a minute later from across the world, they might both hit the same cache at Cloudflare or Google.

The authoritative server (that's plcdns) also caches. When someone queries a DID for the first time, plcdns fetches the document from plc.directory—this takes 50-200ms. Then it caches that document for 5 minutes. During those 5 minutes, any query for that same DID uses the cached document. Response time drops to under 1ms.

What's fascinating is how these layers compound. The first person to query a DID waits 200ms. The second person (same machine) waits 0ms. The hundredth person (different continent) might wait 0ms if they share a recursive resolver with someone who queried recently.

The PLC directory only sees the first request. Everything else is handled by the caching infrastructure that DNS has been building for 40 years.

Real World Examples

Let's look up the official Bluesky account :

$ dig _handle.z72i7hdynmk6r22z27h6tvur.plc.atscan.net TXT +short
"bsky.app"

$ dig _pds.z72i7hdynmk6r22z27h6tvur.plc.atscan.net TXT +short
"https://bsky.social"

Or the Bluesky moderation service :

$ dig _labeler.ar7c4by46qjdydhdevvrndac.plc.atscan.net TXT +short
"https://mod.bsky.app"

Here's how it looks using the DNS tool at ping.sx :

Try It Yourself

The code is on Tangled . Run it locally:

go run . -port 8053
dig @localhost -p 8053 _handle.z72i7hdynmk6r22z27h6tvur.plc.atscan.net TXT

Will This Change Anything?

No. The AT Protocol ecosystem is doing fine without DNS-based resolution. The APIs work, the clients are fast, and nobody's asking for this.

But that's not really the point. The point was seeing if DNS could bridge two protocols, and learning how DNS caching actually works along the way.

And the point was that few hours after seeing a Nostr post, I had a working prototype using Claude 4.5 Sonnet. That's pretty cool.

Thanks to Tim Bouma for the inspiration. Sometimes the best projects are the ones nobody asked for.