SD System Design In Depth
0%
lesson system-designscalingstateless

Horizontal vs vertical scaling

Module 1.1: Foundations & System Invariants Updated Sep 17, 2026
📄 Cheat Sheet
System Design BASICS: Horizontal vs. Vertical Scaling
Gaurav Sen System Design BASICS: Horizontal vs. Vertical Scaling Watch on YouTube ↗

Still the clearest whiteboard explanation of scale-up versus scale-out, including the consistency and network costs horizontal scaling introduces; kept as primary.

0:00 / --:--

Under the Hood: Scale-Up vs. Scale-Out Physics

Scaling is the mechanism of expanding system throughput when inbound request volume exceeds existing processing capacity. The two foundational vectors—Vertical Scaling (Scale-Up) and Horizontal Scaling (Scale-Out)—impose radically different hardware, operational, and architectural trade-offs.

Architectural Comparison

flowchart TD subgraph Vertical ["1. Vertical Scaling (Scale-Up)"] C1["Clients"] --> S1["Single Giant Node (128 vCPU, 1TB RAM)"] S1 --> DB1[("Local NVMe")] NoteV["Hardware ceiling, non-linear cost curve, downtime for upgrades, single point of failure."] end subgraph Horizontal ["2. Horizontal Scaling (Scale-Out)"] C2["Clients"] --> LB["Layer 4 / 7 Load Balancer"] LB --> N1["Worker Node 1"] LB --> N2["Worker Node 2"] LB --> N3["Worker Node N..."] NoteH["Stateless instances, elastic auto-scaling, fault isolation, requires distributed state management."] end

Engineering Realities & Trade-Offs

1. Hardware Limits vs. Distributed Complexity

Vertical scaling upgrades existing nodes (e.g., transitioning an instance from 8 cores to 128 cores). It requires zero application code refactoring and introduces no distributed network latency. However, it hits a ceiling: the largest machine or instance size available, with diminishing returns from NUMA memory-node crossing penalties and memory bandwidth, and price premiums at the largest or specialised sizes (within an instance family, cloud pricing is roughly linear per vCPU). Furthermore, taking the single machine down for hardware maintenance produces instantaneous total outage unless paired with a hot standby.

2. Stateless Tiering as the Prerequisite for Scale-Out

Horizontal scaling adds commodity nodes behind a load balancer. It offers far more headroom and fault tolerance, although shared state, coordination and hot keys keep real gains below linear—if a worker node dies, health checks drop it from the pool without user impact. However, horizontal scaling requires the application tier to be strictly stateless: user sessions, in-flight jobs, and persistent data must move to external shared state layers (Redis clusters, distributed relational databases, or object stores).

3. The Hybrid Modern Standard

Production systems rarely pick one dogmatically. Modern engineering pairs vertical optimization with horizontal elasticity: right-size individual nodes for the workload (for latency-sensitive services, fitting within one NUMA node avoids cross-socket memory penalties, but the right size is workload dependent), then scale those standardized units horizontally behind load balancers.

Worked example: when to scale up and when to scale out

Suppose an API tier handles 2,000 requests per second at peak, and load tests show one 8 vCPU instance sustains about 600 requests per second at 60% CPU while meeting the latency target. Traffic is expected to triple within a year.

  • Today: 2,000 / 600 is about 3.4, so 4 instances meet peak. To survive losing one instance (N+1) you run 5.
  • Next year: 6,000 / 600 = 10 instances, 11 with one spare. The load balancer, health checks and deployment pipeline do not change; only the instance count does.
  • Vertical alternative: one 64 vCPU instance might handle about 4,000 to 4,500 requests per second (rarely a perfect 8x, due to lock contention and memory bandwidth). It is simpler, but it is still a single point of failure, and a restart for patching is a full outage unless a second machine stands by.

The database behind it is a different story. If each request makes one indexed read, 6,000 reads per second is well within a single well-provisioned PostgreSQL or MySQL primary with read replicas. Scaling the database vertically first, then adding read replicas, then partitioning only when writes or data size demand it, is the standard progression.

Trade-off table

DimensionVertical (scale up)Horizontal (scale out)
Code changesUsually noneTier must be stateless or state must be partitioned
Failure impactOne machine failure is a full outage unless a standby existsLosing one of N nodes removes about 1/N of capacity
CeilingLargest available instance sizeCoordination and shared dependencies, not machine size
Cost curveRoughly linear per vCPU within an instance family, jumps at the largest or specialised sizesLinear in node count plus load balancer and operational overhead
UpgradesResize often requires a restartRolling replacement with no downtime
Best fitDatabases, early-stage systems, workloads needing large shared memoryStateless web and API tiers, workers, caches with partitioning

Failure modes to watch

  • Hidden state: local file uploads, in-memory rate limit counters or caches that assume one node silently become wrong with several nodes.
  • Thundering scale-out: an autoscaler that adds 20 instances at once can open 20 new connection pools against the database and overload it.
  • Uneven load: long-lived connections (WebSockets) stay on old nodes after scale-out, so new nodes sit idle until connections are rebalanced.

How real systems do it

Stack Overflow famously served very high traffic for years from a small number of powerful SQL Server machines, a deliberate vertical choice for the database. Most large web companies run stateless application tiers behind load balancers and autoscaling groups, and keep sessions in a shared store such as Redis or in signed tokens so any node can serve any user.

Check yourself Question 1 of 3
Prerequisite for scale-out recall
From: Engineering Realities & Trade-Offs

What must be true of an application tier before you can scale it out by adding nodes behind a load balancer?

Key Takeaways

Vertical scaling avoids distributed complexity but hits the largest-instance ceiling, price premiums at the top sizes, and single-point-of-failure risks.
Horizontal scaling provides fault isolation and elastic headroom, but demands strict stateless application architecture.
Modern production systems scale the compute tier horizontally while scaling the database tier via read replicas and sharding.
Was this lesson helpful? Spot an issue or have a suggestion? Let us know on GitHub.
Report an issue