Top
Best
New

Posted by TangerineDream 11 hours ago

Saving 100 terabytes of memory by optimizing 1.1.1.1's DNS cache(blog.cloudflare.com)
625 points | 189 comments
lpapez 9 hours ago|
This is the right way to deliver software.

Produce working product first, validate the idea, stabilize the business, start generating profit, and then you can start optimizing your costs.

In fact optimization is by far the easiest part of the process because there are many system programming experts on this HN thread who consider these optimizations to be trivial.

sandeepkd 4 hours ago||
Its a yes if you do not know the domain space, query patterns well enough and also if the cost of optimization or time for optimization may have detrimental impact to business. In this case it most likely means that the crowd in the room did not anticipate much on this in early phases and no one in the room pointed these things out. The irony is that these performance and disk numbers are heavily discussed as a part of system design interviews.

> In fact optimization is by far the easiest part of the process because there are many system programming experts on this HN thread who consider these optimizations to be trivia

This is a misconception when you including roll out as a part of the change too, changing data once its running in production is hard, changing the data structure is even harder and when you talk about making changes in cache which is at the hot path its probably the hardest. Looking at the graph at the end it looks like it took them 4+ months to roll out the changes after optimization.

switchbak 1 hour ago||
“changing data once its running in production is hard, changing the data structure is even harder”

100% agreement on this. There are a class of optimizations that can happen transparently. Those can happen at any time, and are fine to defer. Not all profiling and scalability improvements fall into this bucket. Some are very expensive to roll out, and ignoring these concerns can cause huge headaches down the line. Not fun to hear, but it’s definitely true. Even with LLMs, this can still be a huge challenge.

brainless 2 hours ago|||
I do not think Cloudflare was a less-than-peers optimized product when they launched. This is one of their blog posts which describes taking one aspect even further.

I think Cloudflare became big only because they were so much more optimized than others that they offered some services for free that others were not offering. If running costs are high, you only burn (VC) cash and then you exit.

vanviegen 8 hours ago|||
Or optimize a bit earlier and prevent having to scale out to a bazillion systems.
bcrosby95 8 hours ago|||
The way I usually prevent having to scale out to a bazillion systems is never getting more than 10 users.
bigbuppo 5 hours ago|||
And that's why I charge $10,000,000/user/mo.
steve_adams_86 8 hours ago||||
I wonder why Cloudflare didn’t think of this
kevin_thibedeau 7 hours ago||
This is Broadcom's business model
gerdesj 6 hours ago||
Quite. I was a VMware fanboi (25+ years, man and boy)

I still look after a few VMware estates and a lot of Proxmox ones (that used to run VMware).

Hilariously, VMware is described as "enterprise class", which I can only conclude means MVP and a bit wanky.

Today I repaired a Proxmox HA + Ceph node using boring old normal Linux skills and as it turns out I have 30 years of those. Part way through a remote v8 to 9 upgrade I think I lost comms due to using OpenvSwitch for networking and despite using tmux for the upgrade session. Anyway, the Proxmox ISO was useless for rescue but the classic systemrescuecd worked nicely and I could run dpkg in a chroot.

VMware "used" Linux and never really gave back. I don't miss fixing vCentres and all the other nonsense that "Enterprise" wankery has foisted on me over the years.

taneq 5 hours ago||
When I was first getting into software dev, I thought 'enterprise' meant 'industrial grade', 'powerful', 'high-performing'.

Then I actually met some enterprise software, and realised that it means 'expensive', 'bespoke', 'one-off', and usually 'janky'.

phoghed 5 hours ago|||
Enterprise means it has SSO and a support contract
jacquesm 2 hours ago|||
It means you are paying for a support contract. Whether you actually have one time will tell.
esseph 4 hours ago|||
Lol, so true
bigbuppo 5 hours ago||||
Enterprise quality software is a just a DOS application, probably written for dBase III, that has been rolled forward to the present day.
elcritch 1 hour ago||
Those old school systems are often much more stable than any newer systems. Autozone looks to use something like that and I’ve never seen them have issues as a customer.
Nursie 2 hours ago|||
To me it always meant needlessly complex and overspecced for what's needed. I think probably due to Java's enterprise years.

Why solve the problem directly when you can abstract everything away into FactoryFactoryImplementationInterfaceFactorys, and have something that is both a memory-hog and completely unassailable to any normal programmer seeking to understand it or make changes?

forgot-my-pw 7 hours ago||||
The art of premature optimizations
bch 8 hours ago||||
The Art of Production
froh 8 hours ago|||
pro move. made my evening.
scottlamb 3 hours ago||||
You're never going to get promoted with that attitude!

I'm joking...but not entirely. It sounds impressive on a promo packet when you say you've saved 100 TB of RAM / $$$ through whatever technique. But it sounds a lot less impressive when you say if this system grows to this size in x years, I will have saved 100 TB, especially when no one yet knows how large the system will really be in that time or what the cost of RAM will be. I dunno, maybe if you say that x years ago, I made a decision that now is saving us 100 TB, that's kinda impressive, but you're also getting credit for it x years after you did the work. It also doesn't have the implication that it must be inherently complex/hard because some other smart person chose the other way. And there is a bias to care more about recent accomplishments. So I don't really think it'd be valued the same at all.

Also, in general big tech (at least Google) prefers growing the userbase over improving efficiency. Periodically efficiency is rewarded, e.g. when RAM cost suddenly balloons or some big must-have feature has suddenly used up capacity planned for something else. You get rewarded for doing efficiency work on demand, not eagerly.

I once got a $100 peer bonus for finding 100,000 cores that were essentially stranded by an accounting error in another team's migration script.

otterley 42 minutes ago||||
Remember that everything has an opportunity cost. Running a lot of servers might cost $10 million annually, but if the product team had to choose between a project that would recoup $5 million of that vs. an opportunity to earn $50 million ARR for the same amount of work, the logical answer would be obvious.
Dylan16807 2 hours ago||||
It was already reasonably lean. If they had 10 bazillion systems, they now need somewhere between 6 and 8 bazillion systems.
dakolli 3 hours ago|||
You can build foundations that aren't extermely optimal but have future optimisations in mind.
nine_k 5 hours ago|||
This assumes that you have plenty of cash to burn in the process, which is approximately correct for VC-backed ventures, and for offshoots of large corporations that play a lomg game.
aeonfox 4 hours ago|||
> start generating profit, and then you can start optimizing your costs

Good thing they jumped on that as soon as they were profitable instead of burning cash. Oh wait...

I think a distinction to draw here is that Cloudflare had relatively large capital raises and were almost immediately profitable¹. They had the luxury of throwing away money. Judicious optimisation makes sense for scrappy start-ups, especially when trivial optimisations like these could easily be farmed off to an agent.

¹ https://timeline.www.cloudflare.com/

casey2 8 hours ago|||
This reasoning assumes you have access to infinite runway. You don't.
lpapez 8 hours ago|||
Exactly, and you need to start turning a profit before the end of that runway. Even if that means running code that is suboptimal.
ramon156 7 hours ago||
i suppose you could say the same about buying a house. just make that initial 300.000 and from there on out its easy. everything looks better on paper
topato 5 hours ago||
My house is a ~700 sqft. condominium, gov. subsidized for lower income individuals, and even my mortgage is more than 300k… maybe I’m just basing my info off of coastal city prices, but is it possible to buy a reasonably nice home located in a reasonably nice amerikkkan city… for $300k in 2026?
esseph 4 hours ago||
That would buy you thousands of square feet and often several acres within 20 minute drive to a lot of US city downtown areas.
AlotOfReading 1 hour ago|||
Can you ground the discussion by mentioning what you think these cities are? Taking Columbus, OH as the most average of American cities and a 20m isochrone map from city center, there are currently 0 parcels for sale with 3+ ("several") acres under $300k. There are a few within 30m drive, one of which even has a possibly habitable structure. The rest are bare agricultural land you'd need additional investment to actually live on.
8n4vidtmkvmk 3 hours ago|||
Not from what I've seen. The desirable neighborhoods are 500-600k. Suburbs outside major city
catlifeonmars 3 hours ago|||
Desirable neighborhoods are by definition expensive. The trick is to find a neighborhood you like where your home can just be a home and not a top-heavy investment.

Acknowledging this isn’t always easy or possible, but just pointing out that this is a self reinforcing problem.

hdjrudni 1 hour ago||
> The trick is to find a neighborhood you like where your home can just be a home and not a top-heavy investment

I meant desirable for me to live there, not as an investment. Who wants to buy a home in place they don't want to live?

esseph 3 hours ago|||
You didn't read what I said.

I mentioned acres of land. You normally don't have multiple acres of land in the suburbs.

hdjrudni 1 hour ago||
Well then you didn't read parent's comment

> is it possible to buy a reasonably nice home located in a reasonably nice amerikkkan city… for $300k in 2026?

Who wants acreage? We want homes.

esseph 38 minutes ago||
> is it possible to buy a reasonably nice home located in a reasonably nice amerikkkan city… for $300k in 2026?

What does "city" mean to you? For some, it's 500 people, or 5,000. For some, it's 5 million. Define that first. The US is a big place, and I know people that don't live within 50 miles of another human.

Otherwise:

https://www.zillow.com/homedetails/424-Olive-St-Kansas-City-...

4 bed, 3 bath, 1,580 sq ft, beautiful! $342,500, built in 1900.

https://www.zillow.com/homedetails/3508-N-College-Ave-Kansas...

4 bed, 4 bath, 2,295 sq ft, $365,000, built in 2022.

rcxdude 6 hours ago||||
This reasoning is largely centered around the runway being finite. You obviously can't have costs so high you are making a huge loss, but also there's little value in improving margins past profitability until you actually have a stable segment of the market.
inopinatus 7 hours ago||||
we are all perfectly smooth, round, and filled with an incompressible liquid
rexpop 8 hours ago|||
Every startup is one bet in a Martingale strategy played by the class of people who remain solvent when you bust.
robocat 6 hours ago||
The median return for a startup is $0. Take care when trying to extrapolate cause and effect.
tonymet 6 hours ago|||
Only if you have loads of capital
MuffinFlavored 6 hours ago|||
> Produce working product first, validate the idea, stabilize the business, start generating profit,

not everybody is so lucky to be able to go in that order? The first part requires upfront capital/investment?

phoghed 5 hours ago||
So obviously you start at optimization
sieabahlpark 6 hours ago||
[dead]
irdc 11 hours ago||
This is why system programming still matters.

Looks like they're missing the obvious optimisation of putting the record data right after the CacheEntry members instead of allocating memory separately though. But that might just be me as a C-programmer talking and not be all that easy in Rust.

mkeeter 11 hours ago||
For the curious, this is technically possible in Rust using a dynamically sized type [1], but in practice is difficult and doesn't really play nice with the rest of the language. The nomicon entry concludes with "Yes, custom DSTs are a largely half-baked feature for now." [2]

[1] https://doc.rust-lang.org/reference/dynamically-sized-types....

[2] https://doc.rust-lang.org/nomicon/exotic-sizes.html

cakoose 9 hours ago|||
> putting the record data right after the CacheEntry members

I assumed they couldn't do that because they're using it with some kind of generic HashMap<K, V>. In that situation, can "V" be dynamically sized?

A dynamically sized "V" would mean you can't have an array of them, which might preclude some hash map implementations.

esterna 9 hours ago|||
> All type parameters have an implicit bound of Sized. The special syntax ?Sized can be used to remove this bound if it’s not appropriate.

, which HashMap does not do, i.e. the keys and values have to have a statically known size.

f311a 9 hours ago|||
Unfortunately, Rust is not a good choice for this kind of tricks. This is where Zig shines. In Rust, you can’t even use proper arenas, which can help a ton with allocations.

Cloudflare started to pick Zig recently, for projects, that have memory constraints.

afdbcreid 8 hours ago|||
> In Rust, you can’t even use proper arenas

You definitely can and this is done a lot. What you might mean is that you can't use standard library's collections with them (this is getting stabilized soon!) and have to use third-party, but that is a different thing than "can't use arenas".

> Rust is not a good choice for this kind of tricks.

Rust can do those tricks, but it's true that it is hard than in C or Zig. That said there are often crates to help.

f311a 3 hours ago||
Stabilized soon, really? They did not stabilize it after 10 years and were thinking about different approach. I thought it’s dead.
kibwen 1 hour ago||
Yes, really. The design has been decided upon ( https://hackmd.io/nNHdKkp1TTK7jat0I-ABqA ) and the implementation has been updated to match ( https://github.com/rust-lang/rust/pull/157428 ). The stabilization PR is just waiting on final approval by the relevant team members, with no remaining concerns currently listed: https://github.com/rust-lang/rust/pull/156882#issuecomment-5...
chlorion 4 hours ago||||
I'd like to know why I can't use arenas in rust? Especially considering that I have used them before in rust.
f311a 3 hours ago||
You can’t allocate collections without nightly or without reimplementing them in the library. Every implementation uses it’s own set of trade offs to provide safety in unsafe implementation.
kibwen 1 hour ago|||
Rust supports arenas just fine ( https://crates.io/crates/bumpalo ), and if you mean the support for using custom allocators in the standard library collections, that's as stable as Zig is.
sdcfgy 10 hours ago|||
System programming always matters. Things are cheap until they aren't one day.
tehlike 9 hours ago||
things are cheap until you reach a scale.
9dev 7 hours ago|||
Things are cheap until they are someone else’s problem, I say!
listeria 10 hours ago|||
Depends on how the CacheEntry is stored, it's probably stored in a slice of &[CacheEntry] which precludes storing the record data alongside it as the size of each entry must be fixed.
irdc 9 hours ago||
This is where hand-rolled intrusive data structures, as are traditional in C, really shine.
jiggawatts 6 hours ago|||
I wish more programming languages implemented record types as seen in databases, where dynamically sized fields are packed into a contiguous area of memory.

The CloudFlare manually implemented a clumsy version of this.

Wouldn’t it be nice for the compiler to manage this for you in the same way that your database engine does when it saves a “row”?

anitil 3 hours ago||
> dynamically sized fields are packed into a contiguous area of memory

Are you able to explain this? Do you mean an N sized array where each entry is either a value or a pointer to a value where the 'pointed-to' values are after the end of the array?

I'm trying to underatnd how you'd do this without having to parse M-1 elements to get the Mth entry if you did a [{size0, value0}, ....., {sizeN, valueN}] arrangement

toast0 2 hours ago||
I think they mean the cache entry is a collection of dynamically sized fields. It would be nicer to store that as a single contiguous allocation, rather than a bunch of pointers to individually allocated dynamically sized items. At least in this case, it might.

In a row oriented database, you get a contiguous spot for the whole row even when there are multiple variable width fields.

cobalt 11 hours ago||
less ergonomic, but still totally doable
grep_it 53 minutes ago||
This reminds me how you can save a bunch of bytes just by making sure your structs are aligned. In go for example:

  type Wasteful struct {
    a int16
    b int
    c byte
  }

  type Aligned struct {
    b int
    a int16
    c byte
  }

Will have sizes of 24bytes and 16bytes (on a 64bit system). Same data 8bytes more. If you are storing millions of those objects, then it adds up.
masklinn 41 minutes ago|
Rust does that automatically unless you switch to the C layout.

In langages that don’t there’s a tension between memory use and human readability / consistency of the layout. There are also other domains which can be affected e.g. databases, it’s a concern / issue when using postgres.

strenholme 11 hours ago||
With my own MaraDNS, I aggressively optimized the memory usage of blacklist entries by having a single really big malloc() to allocate the memory for the entries, then traversing that memory block for potentially blacklisted entries.

When I was using one malloc() per entry, a large blacklist took up 237 megabytes of memory. The same blacklist, once optimized to be loaded with a single malloc() call, only took up 9.5 megabytes of memory.

https://samboy.github.io/blog/entries/MaraDNS.html#BlogEntry...

badatnames 5 hours ago|
Why do I always find interesting new Twitter accounts just as the person is leaving :)
ww520 3 hours ago||
Not sure what they use to hold the cache key and entry. If a hashmap is used, then a radix tree (adaptive radix tree) would be better in saving memory space. Most of content of the qname field of the CacheKey is hostname, like www.site.com. The reverse version com.site.www fits nicely in navigation path of a radix tree. The common prefixes like "com." are shared and compressed in the parent nodes of the tree.

Even a BTree with compressed prefix keys can save space in the qname.

vinkelhake 10 hours ago||
These seem like some fairly standard approaches for reducing memory usage. I can't help to think that the approach of joining several distinct list into a single one in some way undercuts Rust's safety guarantees.

If you previous had three distinct Vec objects, then Rust would guarantee that you can't index out of bounds. If you now put all those objects into a single Vec and rely on offsets, then you now open the door to indexing out of range of these sub-slices without any panics.

It's a minor point, and it doesn't really invalidate the optimization, but I'm surprised the article didn't mention it.

ratorx 10 hours ago||
I think it’s more of a time vs code tradeoff, if done properly.

For example in the Vec case, you could theoretically build an alternative which encodes the “three sections” property internally, and ensures correctness at construction time for the pointers. Not as completely safe as a Vec, but you can still get similar benefits for the “business logic”.

But I agree, just having a custom structure that does not provide a safe wrapper around this would be sacrificing standard guarantees.

NIckGeek 2 hours ago|||
You can make a wrapper type that abstracts the offset lookup logic with a safe interface. If it's a transparent struct then rust will compile it away into nothing but you still get the abstraction in your code.
afdbcreid 8 hours ago|||
> I can't help to think that the approach of joining several distinct list into a single one in some way undercuts Rust's safety guarantees.

Not really. You just need to make the underlying fields private and provide methods to get slices to the data you need.

vsgherzi 10 hours ago|||
you could always do a .get into the vector and handle the error, it doesn't necessarily need to panic.

Thank being said in this case it should be impossible to index out of bounds so maybe a panic is warented.

pocksuppet 7 hours ago|||
It's the exact thing Rust is made to protect against, on a more local scale. Every memory corruption bug is just an out-of-bounds index that wasn't protected against.
bvanheu 7 hours ago||
is dangling pointers reuse memory corruption bug from out of bound index?
FpUser 10 hours ago||
Tools exist to serve us, not the other way around.
asgraham 8 hours ago||
Sure, and usually one of the ways Rust serves us is with safety guarantees.

Which isn’t to say this optimization is a bad idea, just to say it’s sort of a straw man to imply coding in Rust to take advantage of safety guarantees is “serving Rust”

Agentlien 32 minutes ago||
One of my proudest professional moments was when me and three others managed to reduce memory load of the game Wavetale from 20+GiB to under 3GiB so we could port it to Nintendo Switch.

The 100 TiB number almost gives me vertigo. Though in this context it was "just" 50%

adzm 13 minutes ago|
I'd love to hear what was taking up that 17GiB if you can share, even if it is commonly optimized things like packing, still fun to hear about
zamalek 41 minutes ago||
The intermediate level Rust dogma is to try your hardest to avoid the heap, and to tear your hair out at the throne of monomorphization. While both are broadly true, it's articles like this that show that a single pointer (or call) indirection can sometimes be better.
BikiniPrince 5 hours ago||
Funny thing about cloudflare. I have a dns warming script that uses their top 1k or 10k addresses. Then when my master starts up it warms the entire cache. Everything else uses memcache so the cluster is nice and toasty. As far as I can tell no one else releases domain statistics like them.
1saadcodes 6 hours ago|
We're finally seeing more appreciation for this kind of engineering. Not everything needs to be solved by throwing more hardware at the problem
More comments...