Fundamentals

Scaling

Vertical vs. horizontal, and which of compute, storage, or connections is actually your bottleneck.

9 minEasyscalabilityfundamentals

"Scaling" gets used as a single word for a handful of distinct problems. Naming which one you're solving is most of the battle.

Vertical vs. horizontal

Vertical scaling — a bigger machine — is the right first move far more often than interview prep culture admits. It has no coordination cost and no new failure modes. It stops being the answer when you hit a ceiling (hardware limits, or a single point of failure you can no longer accept), not on day one.

Horizontal scaling — more machines — buys you headroom past that ceiling and resilience against losing one machine, at the cost of needing to coordinate state across them.

Instagram is a well-documented real example of this order: its main Postgres database ran vertically — on progressively bigger single boxes — for years before the team eventually sharded, specifically because vertical scaling had no coordination cost and horizontal scaling did. It's worth citing as evidence that horizontal scaling is a response to a specific, named ceiling, not the default correct answer.

type ScalingChoice = {
  approach: "vertical" | "horizontal";
  buys: string;
  costs: string;
};

const dbScaleUp: ScalingChoice = {
  approach: "vertical",
  buys: "No coordination cost — a single Postgres primary going from 8 to 32 vCPUs can absorb several times more write throughput with zero application changes",
  costs: "A hard ceiling once you hit the largest instance size available, and it stays a single point of failure until you add a replica",
};

Vertical

8 vCPU

32 vCPU

Ceiling

largest instance available

Horizontal

App instances (x3)

Load Balancer

distributes across them

Client

The three things that actually get scaled

  • Compute — stateless request handling. Usually the easiest to scale horizontally, since a new instance needs no data to start serving traffic.
  • Storage — where scaling gets hard, because data has to live somewhere and that somewhere has to stay consistent, or you've decided to accept it won't (see the next lesson).
  • Connections — a proxy or load balancer sitting in front of both, routing traffic and hiding the fact that there's more than one of anything behind it.

Read-heavy vs. write-heavy

Most systems are read-heavy by a wide margin, which is why caching and read replicas dominate scaling discussions — they multiply read capacity without touching the harder problem of write throughput. A write-heavy system (an ingestion pipeline, a metrics collector) needs a different toolkit: partitioning writes across shards, buffering with a queue, and batching.

Say out loud, early, which side of that split the system you're designing falls on — it changes which of the next lessons' building blocks actually apply.