Friday, August 28, 2026
Back to Home
Cloudflare Rewrites 1.1.1.1 DNS Caching in Rust, Cuts Memory by a Factor of 24

Cloudflare Rewrites 1.1.1.1 DNS Caching in Rust, Cuts Memory by a Factor of 24

T
Techpivo
·5 min read·1 views
Quick Brief
  • Cloudflare reworked 1.1.1.1's negative DNS cache in Rust, trimming per-server memory about 24x.
  • Per-shard moka LRU plus Bloom-style pre-filter replaced a hashmap plus fixed 1024-entry list.
  • Operators of other resolvers can copy the split-cache and working-set LRU sizing pattern.
📌Key Points
1Cloudflare cut per-server memory on 1.1.1.1 by roughly 24x, from about 4 GB to 160 MB, by rewriting the negative DNS cache in Rust.
2The new cache uses the moka crate's per-shard LRU with TinyLFU admission policy and rustc_hash's FxHashMap for the positive cache.
3Negative responses such as NXDOMAIN and NODATA dominated cache memory, making them the primary target of the optimization.

Cloudflare has reengineered the caching layer of its public 1.1.1.1 resolver in Rust, reducing per-server memory consumption roughly 24-fold. While maintaining the same throughput, according to a deep-dive engineering post published on the Cloudflare Blog. The rewrite targets the "negative cache," the data structure that stores failed or non-existent DNS lookups. And demonstrates how a careful choice of data structure can transform operating costs at hyperscale. This guide covers How we saved 100 terabytes of memory by optimizing 1.1.1.1’s DNS cache in detail. This guide covers 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, such as NXDOMAIN or NODATA, dominate real-world traffic. Cloudflare's engineers noted that although negative answers account for only a fraction of. All lookups, they were responsible for the. Majority of memory used by the cache. The previous implementation combined a concurrent hashmap with a fixed-size 1024-entry least-recently-used (LRU) list. While correct, the design forced the resolver to keep a large number of. Low-value entries in memory. Because the LRU window was too small relative to the working set.

Why did Cloudflare rewrite the 1.1.1.1 negative cache? — How we saved 100

According to the post, the team replaced. That architecture with a single sharded LRU cache per shard, eliminating the hashmap entirely. They also added Bloom-filter-style optimizations: if a query name appears frequently. But the answer is consistently negative, the system skips the upstream lookup and. Returns the cached negative response directly. Together, these changes cut per-server memory from a peak of roughly 4 GB. To a working set near 160 MB, a 24x reduction.

What technical changes made the biggest difference? — How we saved 100

What technical changes made the biggest difference?

Two Rust crates anchor the new design: rustc_hash (FxHashMap) for the positive cache, prized for its speed despite weaker collision resistance, and moka for the negative cache, which provides a production-grade, segmented LRU implementation with TinyLFU admission policy. Each shard runs its own moka instance, sized to roughly one fourth of. The configured memory budget. So a single shard can be sized to fit comfortably in CPU L2 cache.

How does this affect users of 1.1.1.1? — How we saved 100

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 consolidation removed redundant lookups and reduced lock contention. Which had previously been visible 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. Such as those generated by misconfigured applications, ad networks probing trackers, and certain malware families. Operators running their own recursive resolvers, including Unbound, BIND. And Knot Resolver, can borrow the same idea: separate the positive and negative. Cache, size the LRU to the actual working set. And consider 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 is as important as positive caching, especially. When a large share of upstream traffic is junk.

What This Means

The economics of public DNS are unforgiving: every byte stored in cache costs. Money across hundreds of points of presence. Cloudflare's 24x reduction is not just 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 illustrates a broader trend in which operators migrate hot-path network services from Go to Rust to reclaim 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. memory headroom, following similar moves by Linkerd, Discord, and the Linux kernel's bpfilter team.

What's Next

Cloudflare engineers indicated 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's tuning changes are upstreamed, and for competing resolvers such as Google Public DNS and Quad9 to publish comparable 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 sacrificing throughput, a case study in how data-structure choice, not raw. Hardware, drives efficiency at internet scale.

Frequently Asked Questions

What did Cloudflare change in 1.1.1.1?
It replaced a hashmap-plus-LRU negative cache with a per-shard moka-based LRU written in. Rust, cutting per-server memory use about 24x.

Why is negative DNS caching important?
Failed lookups (NXDOMAIN, NODATA) make up a large share of resolver traffic and historically dominated cache memory use. So optimizing them pays off quickly.

Does this change affect query latency?
Yes, repeated queries against dead or blocked names now resolve directly from cache. Reducing upstream load and response time.

Related Resources

For more context, check our related article on this topic.

Frequently Asked Questions

What specific Rust crates did Cloudflare use for the new 1.1.1.1 cache?
Cloudflare used moka, a segmented LRU with TinyLFU admission, for the negative cache, and rustc_hash's FxHashMap for the positive cache.
How much memory did the Rust rewrite save on 1.1.1.1 servers?
Per-server memory dropped from a peak of roughly 4 GB to a working set near 160 MB, about a 24-fold reduction.
Why target the negative cache instead of the positive cache in DNS resolvers?
Failed lookups such as NXDOMAIN and NODATA dominate cache memory in real-world traffic, so optimizing them yields the largest gains.

Discussion