“Design for scale” is one of those phrases that quietly justifies a lot of complexity. The useful version is narrower: build so that the next order of magnitude is a configuration change, not a rewrite — and stop there.
Three rules that hold up
- Make the boundary the contract. If your modules talk through a stable, parameterized interface, you can swap the implementation behind it (a bigger database, a queue, a cache) without touching callers.
- Prefer boring, single-writer state. Most scaling pain is really coordination pain. One writer, clear ownership, and idempotent operations beat clever distributed cleverness almost every time.
- Measure before you shard. The cheapest scale is the query you did not run and the index you did add.
None of this is novel — it is just easy to forget when a shiny distributed pattern is on offer. Scale is earned incrementally, and the best systems look almost embarrassingly simple right up until the moment they need not to be.