resource driven design
I have started designing from resources (CPU, RAM, DISK, NETWORK) instead of from features, frameworks or architecture diagrams, and everything got simpler.
The systems I have seen fail did not fail for lack of abstractions. They failed because nobody was thinking about the hardware underneath.
Cultural disconnect
Engineering is solving a problem in a context: time, team, budget, tools, and the requirements that are written down plus the ones that are not.
Most projects I have joined started from features, then picked tools and patterns and a scaling strategy, and never asked what hardware any of it needed. The Three Big Lies called this out years ago: abstraction sold as progress.
I still do not know what “design for a million users” means. Running on what? How much memory, how many cores, how fast a disk? Same thing I was getting at in thinking in 3d: I want the whole picture before I pick anything.
Software spends its time doing one of two things: computing on the CPU, or dispatching I/O to disk and network. Thinking in resources draws the boundary between them, and once I can see the boundary my performance decisions stop being accidental.
RAM
The bottleneck I hit most often is data no longer fitting in memory. The accepted answer is to scale horizontally with queues, logs, sharding and a distributed processing tool.
I try to do the math first.
- 1 GB of RAM costs roughly $2 per month
- 1 TB costs around $2000 per month
Before I reinvent distributed systems I want to know why the best practice is more complex, more expensive and harder to maintain than buying more RAM. Scale, but at what cost?
CPU
A load is CPU-bound when the data lives entirely in memory: read from RAM, compute in RAM, write to RAM. Performance then depends on computation and memory throughput, not I/O. When I optimize one of these it means fewer cache misses, less data movement, less context switching. It has never meant another message broker.
To stay CPU-bound the data has to be in RAM. Reach for disk or network, both far more expensive than the CPU, and you are not CPU-bound any more.
The questions I ask now
Designing from resources left me with smaller questions:
- what resources do we have, and how will they be used?
- what traffic and data patterns will this see?
- what do the team already know how to operate?
Once I can answer those, the architecture falls out on its own. A system that matches reality instead of aspiration.
Looking at it through resources, the submodules show up on their own:
- read: is it RAM, disk or network, and what are the hardware limits?
- process: where does the computation happen, and which resource does it saturate?
- write: where does the output go, and can it be batched or buffered to cut syscalls?
Boundaries follow resources. Following them is how I find the coupling, the bottleneck and the waste. Less about imaginary problems, more about physics.