Horizontal or vertical scaling: which does your microservice need?
Horizontal scaling adds replicas; vertical scaling adds resources to each one. Most services need both at different points, and the mistake is choosing by habit. The service's own measurements say which ceiling it hits first, and Kubernetes can express either once you know.
By Tudor Pop. Published 2026-10-12.
What does each one change?
Vertical scaling gives a replica more CPU, memory or network: a bigger instance, higher requests and limits, a larger connection pool. It changes nothing about the architecture and it has a ceiling: the largest instance your provider sells, and before that the point where one process cannot use more cores. Horizontal scaling runs more replicas behind a load balancer. It has no ceiling in principle and a long list of conditions in practice: the service must hold no per-replica state the next request depends on, its downstreams must take the extra connections, and whatever coordinates the replicas (a queue, a lock, a database) must not become the new bottleneck.
Which limits do you hit first?
Measure the service under load and watch which resource saturates. A CPU-bound stateless handler saturates its cores evenly and scales horizontally without drama. A service with a large in-memory working set (a cache, an index, a model) hits memory first and scales vertically until the working set no longer fits one instance, at which point it needs partitioning, not more replicas. A service that holds many connections to a database hits the database’s connection limit first, and adding replicas makes it worse; the fix is a connection pooler or fewer, larger replicas. A service that depends on a single lock or a serial queue hits throughput on that coordinator and no amount of either kind of scaling helps until the coordinator is sharded.
How do you measure before you decide?
Load test one replica to its breaking point and record which resource broke: CPU at 100%, memory at the limit, connections refused, latency rising while CPU stays flat. Then run two replicas and see whether throughput doubles; if it does not, the bottleneck is shared and horizontal scaling is buying nothing. Then double the replica’s resources and repeat. Two hours of this tells you more than any architecture diagram, and it gives you the numbers the autoscaler needs: the per-replica capacity and the signal that moves before latency does.
How does Kubernetes express each?
Vertical scaling is the pod’s requests and limits, set from measured usage, and the Vertical Pod Autoscaler where the usage changes slowly and a restart is acceptable. Horizontal scaling is the Horizontal Pod Autoscaler keyed on the signal that limits the service: CPU for compute-bound handlers, a custom metric (queue depth, in-flight requests, connections) for everything else, because CPU is the wrong signal for a service that waits on I/O. Do not run both autoscalers on the same resource of the same workload; they fight. Pod disruption budgets and readiness probes are part of horizontal scaling, not an afterthought, because a scale-down that removes a replica mid-request is an outage the autoscaler caused.
When do you need both?
When the per-replica capacity is too small to be efficient and the total demand is too large for one replica. A replica so small that the runtime’s overhead dominates wastes money horizontally; a replica so large that losing one takes a quarter of the capacity is a reliability risk. The usual outcome is a replica sized vertically to where its throughput per unit of cost is best, then scaled horizontally from there, with the minimum replica count set by what you can afford to lose. Revisit the sizing when the service changes, because the measurements that chose it do not survive a new dependency.
Kitecorp runs this work as part of monolith to microservices and Kubernetes consulting engagements.
Tell us what you are scaling
Send a short description of the system and the deadline. A senior engineer replies by email, and pricing follows a discovery call.
Contact Kitecorp or email admin@kitelang.cloud