How to Tell When You Actually Need to Scale
Every dashboard has a CPU graph, and every CPU graph eventually shows a spike that looks scary. Knowing which spikes actually mean you need more resources, and which are normal and self-correcting, saves you from both premature scaling costs and from waiting too long and degrading service for real users.
Sustained high CPU is the clearest signal, and "sustained" is the operative word. A brief spike during a deploy or a scheduled job is expected, not a warning sign. CPU sitting above 70 to 80% for extended stretches, especially during normal rather than peak traffic, means you're running with no headroom left, and the next unexpected bump in traffic causes real degradation instead of just a line on a graph.
Memory moves slower but bites harder. Unlike CPU, which recovers the moment load drops, memory that climbs steadily and never comes back down usually means a leak somewhere in the app, not a genuine need for more RAM. Throwing more memory at a leak just delays the crash. Worth figuring out which one you're looking at before you scale anything.
Response time under load matters more than either resource metric on its own, because it's what your users actually feel. If response times stay flat as traffic grows, you likely have headroom no matter what the CPU graph shows. If response times climb before resource usage looks alarming, the bottleneck is probably somewhere else entirely, database connection limits, an unindexed query, a single-threaded process, and more compute won't touch it.
When you do scale, vertical versus horizontal is the next decision. Vertical scaling, a bigger instance, is simpler, usually a resize with brief downtime, and the right first move for most small-to-mid workloads. Horizontal scaling, more instances behind a load balancer, adds real complexity around session handling and deployment coordination, but removes the ceiling vertical scaling eventually hits.
The practical rule: watch response time and error rate as your primary signals, treat CPU and memory as supporting diagnostics rather than the trigger itself, and don't scale reactively off one bad day. A real capacity problem shows up as a trend across days or weeks, not a single spike during something unusual.