The boring parts are what make software scale
The boring parts are what make software scale
When people talk about scalability, the conversation quickly jumps to queues, clusters and distributed databases. Those tools have their place. But most applications hit a different limit first: nobody is quite sure where one responsibility ends and the next begins.
I have found that systems become easier to scale after they become easier to understand.
Keep the first version close together
Splitting a young application into services can make every ordinary change surprisingly expensive. A well-structured single deployment is often the better starting point. Modules can still have strict boundaries without requiring a network call between them.
The test I like is simple: can one part be changed without knowing the private details of three others? If not, adding more infrastructure will mostly distribute the confusion.
Measure the path users actually take
Average response time is comfortable and frequently misleading. A slow operation hidden behind a fast average is still slow for the person waiting on it.
I prefer a small set of measurements tied to real flows:
- time until the user can do something useful;
- latency at the 95th and 99th percentile;
- failures grouped by cause, not just status code;
- queue depth or memory pressure when the system is busy.
Instrumentation does not need to be elaborate on day one. It needs to answer the next question you are likely to ask.
Put limits in the design
Unbounded work is one of the easiest ways to turn a small problem into an outage. Lists need pagination. Retries need a ceiling. Buffers need a maximum size. Background jobs need a way to apply backpressure.
These limits can feel arbitrary while the system is quiet. Under load they become part of its behaviour, and it is better to choose them intentionally.
Cache only what you can invalidate
A cache is not free speed. It is another copy of the truth with a delay attached.
Before caching something, I want to know who owns the value, how stale it may become and what event makes the cached version invalid. If those answers are unclear, the cache is likely to trade visible latency for invisible correctness bugs.
Scaling is mostly removing surprises
The strongest systems I have worked with were not the ones with the most technology. They were the ones that behaved predictably: clear ownership, bounded work, useful measurements and failure modes people had already considered.
That foundation is not exciting to draw on a whiteboard. It is what makes the exciting parts possible.