Cloudflare has reengineered the caching layer of its public 1.1.1.1 resolver in Rust, cutting per-server memory use by about 24x. The team kept the same throughput while making this change, as shown in a deep-dive engineering post on the Cloudflare Blog. The rewrite targets the "negative cache," which is the data structure that stores failed or non-existent DNS lookups. It shows how a careful choice of data structure can change operating costs at huge scale. This guide covers the post titled "How we saved 100 terabytes of memory by optimizing 1.1.1.1's DNS cache" in detail.
How we saved 100 terabytes of memory by optimizing 1.1.1.1's DNS cache: Why did Cloudflare rewrite the 1.1.1.1 negative cache?
Negative DNS responses, like NXDOMAIN or NODATA, make up most of real-world traffic. Cloudflare's engineers found that negative answers only account for a small share of all lookups. Still, they used most of the memory in the cache. The old design paired a concurrent hashmap with a fixed 1024-entry least-recently-used (LRU) list. It was correct, but the design forced the resolver to keep many low-value entries in memory. The LRU window was too small compared to the working set.

According to the post, the team replaced that design with a single sharded LRU cache per shard. They removed the hashmap entirely. They also added Bloom-filter-style changes: if a query name appears often but the answer is always negative, the system skips the upstream lookup. It then returns the cached negative response right away. Together, these changes cut per-server memory from a peak of about 4 GB to a working set near 160 MB, a 24x drop.

What technical changes made the biggest difference?
Two Rust crates anchor the new design: rustc_hash (FxHashMap) for the positive cache, valued for its speed even with weaker collision resistance, and moka for the negative cache. Moka gives you a production-grade, segmented LRU with a TinyLFU admission policy. Each shard runs its own moka instance, sized to about one fourth of the configured memory budget. So a single shard can fit in the CPU L2 cache.

Cloudflare also revisited the responder side. A dedicated goroutine-style task now drains the response channel and merges positive and negative cache entries, including the cached SOA record used to compute negative TTLs. This cleanup removed redundant lookups and reduced lock contention. That contention had shown up in flame graphs as a hotspot inside the Go runtime's sema operations.
How does this affect users of 1.1.1.1?
In practical terms, resolvers now respond faster to repeat queries against dead domains. These include queries from misconfigured apps, ad networks probing trackers, and some malware families. Operators running their own recursive resolvers, such as Unbound, BIND, and Knot Resolver, can borrow the same idea: separate the positive and negative cache, size the LRU to the real working set, and add a Bloom filter or small pre-filter for the noisiest names. For developers building DNS-aware services, the post is a reminder that negative caching policy matters as much as positive caching, especially when a large share of upstream traffic is junk.
What This Means
The economics of public DNS are tough: every byte stored in cache costs money across hundreds of points of presence. Cloudflare's 24x reduction is more than a performance win. It directly lowers the cost of serving each query, which matters more as encrypted DNS (DoH and DoT) pushes more processing onto edge servers. The project also shows a broader trend where operators move hot-path network services from Go to Rust to reclaim memory headroom. This follows similar moves by Linkerd, Discord, and the Linux kernel's bpfilter team. Whether you are new to "How we saved 100 terabytes of memory by optimizing 1.1.1.1's DNS cache" or already experienced, the sections below have you covered.
What's Next
Cloudflare engineers noted that future work will focus on sharding policy, smarter TTL handling across CNAME chains, and tighter integration with the company's emerging DNS-level security products, such as 1.1.1.1 for Families. Watch for upstream patches into the open-source moka and rustc_hash crates as Cloudflare shares its tuning. Competing resolvers like Google Public DNS and Quad9 may also publish similar memory benchmarks.
The Bottom Line
By rethinking how negative DNS responses are cached, Cloudflare trimmed memory use by a factor of 24 on 1.1.1.1 without losing throughput. It is a case study in how data-structure choice, not raw hardware, drives efficiency at internet scale.
Frequently Asked Questions
Cloudflare replaced a hashmap-plus-LRU negative cache with a per-shard moka-based LRU written in Rust, cutting per-server memory use about 24x.
Failed lookups (NXDOMAIN, NODATA) make up a large share of resolver traffic and have historically dominated cache memory use, so optimizing them pays off quickly.
Yes, repeated queries against dead or blocked names now resolve right from cache, reducing upstream load and response time.
Related Resources
For more context, check our related article on this topic.