Articles

Horizontal vs Vertical Scaling Explained

Horizontal scaling adds more machines; vertical scaling adds more power to one machine. How each works, their limits, and when to use which.

Chisato Chisato · · 4 min read
Rows of server racks in a data center

Horizontal scaling (scaling out) handles more load by adding more machines to a pool of workers; vertical scaling (scaling up) handles more load by giving a single machine more CPU, memory, or disk. They solve the same problem — a system that’s running out of capacity — with fundamentally different tradeoffs around cost, complexity, and how much of the application has to change to support the approach.

Vertical scaling: the simple first move

Scaling up means resizing an existing machine: more vCPUs, more RAM, faster storage, a bigger instance type. For a database or any stateful service, this is usually the path of least resistance, because it requires no changes to the application — the same single instance just has more resources to work with.

The catch is that vertical scaling has a hard ceiling. Cloud providers offer instance sizes up to a point, and beyond that point there’s no bigger box to buy. It also doesn’t help with availability: a single, larger instance is still a single point of failure, and resizing typically requires downtime or at least a restart.

Horizontal scaling: distributing the load

Scaling out means running multiple instances of a service and distributing traffic across them, usually behind a load balancer. Need more capacity? Add another instance to the pool. This approach scales much further in principle — cloud providers can spin up hundreds of commodity instances more easily than one exotic, oversized one — and it improves availability as a side effect, since the failure of any single instance doesn’t take the whole service down.

The cost is complexity. A horizontally scaled system generally needs to be stateless, or externalize its state somewhere shared, because a request can land on any instance in the pool. That has downstream consequences:

  • Session data has to live in a shared store (like Redis) rather than in server memory, or be encoded in a token the client carries, so any instance can serve any request.
  • Database writes don’t automatically scale just because the application layer did — you’ll likely need read replicas or sharding on the data layer separately.
  • Cache coherence becomes a real question once there are multiple application instances that might each hold a stale local copy of the same data.
  • Deployment coordination matters more — rolling out a new version across many instances safely is what blue-green and canary deployments are designed for.

Comparison

Vertical scalingHorizontal scaling
How it worksBigger machineMore machines
CeilingLimited by largest available instanceEffectively unbounded
Application changesUsually noneOften requires statelessness
Availability impactNo improvement — still one instanceImproves — no single point of failure
Cost curveJumps in large, discrete stepsScales more granularly, pay for what you add
Typical fitDatabases, legacy monolithsStateless web/API tiers, microservices

Why databases usually scale vertically first

Databases are the clearest example of where this tradeoff plays out. A single ACID-compliant relational database is much simpler to reason about than a distributed one, so the typical progression is: scale the primary vertically as far as it reasonably goes, add read replicas to offload read traffic, and only reach for sharding — splitting data itself across multiple database instances — once a single primary genuinely can’t keep up with write volume. Sharding solves real scaling problems, but it also means giving up cross-shard transactions and joins, which is a meaningful application-level cost, not just an infrastructure change.

Where horizontal scaling shines

Stateless services are the natural fit for scaling out: web servers, API layers, background job workers, and anything behind a CDN that doesn’t hold onto request-specific state between calls. Because any instance can handle any request, adding capacity is close to mechanical — spin up another container or VM, register it with the load balancer, and traffic distributes automatically. This is also why container orchestration tools default to describing “how many replicas” rather than “how big is the machine”: the whole model assumes horizontal scaling is the primary lever.

The routing layer matters here too. How traffic gets distributed evenly across a growing pool of instances — and how that distribution stays stable as instances are added or removed — is exactly the problem consistent hashing was designed to solve, particularly for stateful routing like cache or session affinity.

Combining both

In practice, most production systems use both at once rather than treating this as an either/or decision. A typical setup: individual instances are sized (vertical) to a sensible baseline for their workload, and then a pool of those instances is scaled out (horizontal) to handle overall traffic and provide redundancy. Autoscaling groups usually adjust the count of instances (horizontal) in response to load, while the size of each instance (vertical) is chosen once, up front, based on the workload’s per-instance resource profile.

The takeaway

Vertical scaling is the simpler first lever — resize the box, change nothing about the application — but it hits a ceiling and doesn’t improve availability. Horizontal scaling removes that ceiling and adds redundancy, at the cost of requiring the application to tolerate requests landing on any instance, which usually means externalizing state. Most real systems use both: a sensibly sized instance as the unit, scaled out as a pool to absorb load and survive individual failures.

Chisato Chisato · · 3 min read

What Is a Runbook? Incident Response Playbooks

A runbook is a step-by-step document for handling a specific operational task or incident, turning tribal knowledge into a repeatable procedure.

#DevOps #Cloud #Observability
Chisato Chisato · · 4 min read

What Is a NAT Gateway?

A NAT gateway lets private-subnet resources reach the internet outbound while staying unreachable from it, translating private IPs to a public one.

#Cloud #Networking #DevOps