System Design ยท Chapter 04

Scalability, from First Principles

Why an app that flies with a thousand users chokes at a million, and the moves that keep response time flat as the crowd grows.

๐Ÿ—๏ธ
How to read this

The chapter follows one thread: a healthy small app, the moment scale breaks it, and each fix in turn. Anything marked [+] is context added beyond the source lessons to fill a gap. Diagrams are original redraws, not copies of the course art. Color is a language: green = app servers, blue = databases, amber = cache, cyan = load balancer.

01

The one number that defines scalability

Scalability is an application's ability to absorb a growing workload without giving up performance. Concretely: if a request takes x seconds to serve for one user, it should still take about x seconds when a million users hit the system at once. The back end shouldn't buckle under a million concurrent requests, and the time each user waits shouldn't creep up as the crowd grows.

That "time each user waits" is the number everything hinges on. It's called latency, and holding it flat under load is scalability. If latency stays constant as traffic climbs, the system scaled well.

โš ๏ธ
Common exam trap

On a scalable app, rising traffic keeps latency the same or lower โ€” it does not make latency go up. Latency climbing with traffic is the definition of a system that failed to scale.

Scalability in Big-O terms

The same idea shows up in complexity notation. The ideal is O(1) โ€” constant time regardless of data size, like a lookup in a hash map or key-value store. A system or algorithm that runs in O(nยฒ), where n is the size of the dataset, is not scalable: as the data grows, it demands ever more compute and resources just to keep up. [+] The gap is stark at scale โ€” at n = 10,000, an O(nยฒ) routine does 100 million operations to an O(1) lookup's one.

Traffic / dataset size → Latency → O(1) โ€” scales O(nยฒ) โ€” collapses
Figure 1 โ€” Scalability is a flat latency line. The scalable system (green) holds steady as load climbs; the non-scalable one (red) degrades faster and faster.
02

Latency: what you're actually racing

Latency is the time between a user's action and the system's response. Click a button, scroll, request an image โ€” if the reply lands two seconds later, latency is two seconds. Efficient systems chase the minimum, and the whole point of scaling is to keep that minimum from drifting upward as load builds.

Measured end to end, latency splits into two parts you attack differently:

User 1 Network latency travel time, wire A → B cut with a CDN / edge Server 2 Application latency time to process the request DB
Figure 2 โ€” End-to-end latency = network latency (getting there) + application latency (doing the work).

Network latency

The time the network needs to move a data packet from point A to point B. The fix is distance: businesses deploy a CDN (Content Delivery Network) to place servers around the globe as close to users as possible. Those near-user sites are called edge locations โ€” the shorter the physical hop, the lower the network latency.

Application latency

The time the app itself spends processing a request. You bring it down by finding what's slow: run stress and load tests, hunt the bottlenecks that drag the whole system, and remove them (Section 6 catalogs the usual suspects; Section 8 covers the testing).

๐Ÿ’ก
Why milliseconds are worth millions

Latency decides whether an online business keeps a customer. Slow responses make visitors bounce, and research consistently ties high latency to lost users. In MMO games a small lag ruins the experience regardless of a player's reflexes; algorithmic traders run dedicated low-latency networks because ordinary ones can't process events in milliseconds. In 2011 Huawei and Hibernia Atlantic began laying a transatlantic fiber-optic cable between London and New York โ€” an estimated ~$300M project โ€” to shave six milliseconds off trading latency.

03

Two ways to grow: up vs. out

Scaling needs computing power โ€” servers strong enough to handle rising traffic. There are exactly two directions to add it.

Vertical scaling โ€” make one server bigger

Also called scaling up: add power to the existing machine. An app on a server with 16 GB of RAM gets bumped to 32 GB. You're augmenting the hardware under the same app. It's the simplest move โ€” no code refactoring, no complex configuration โ€” so when traffic first starts building, it's usually the right first step.

The catch is a ceiling. A single server can only hold so much compute. [+] Think of a multi-story building: you can keep adding floors, but not up to the moon. When demand outgrows one machine, you stop stacking and start spreading.

Horizontal scaling โ€” add more servers

Also called scaling out: add more machines to the existing resource pool, raising the system's total compute. In theory there's no limit โ€” keep adding servers, then whole data centers. It also unlocks dynamic scaling: grow and shrink capacity in real time as traffic rises and falls through the day, something vertical scaling can't do.

Vertical โ€” scale up hard ceiling 16 GB 32 GB Horizontal โ€” scale out S1 S2 S3 + โ€ฆ no hard limit → add servers, then data centers
Figure 3 โ€” Up hits a ceiling; out keeps going. Vertical grows one box until hardware runs out; horizontal multiplies boxes.
04

Cloud elasticity, and why the cloud won

The single biggest reason cloud computing went mainstream is dynamic scaling. When traffic climbs, the cloud adds servers to the resource pool; when it drops, it removes them. Paying only for the hardware actually used โ€” stretching out under load and contracting back when it eases โ€” is cloud elasticity, and the economics of it save businesses money every day.

A second payoff comes for free: with many server nodes on the back end, the site stays online even if a few nodes crash. That property is high availability โ€” the natural companion to horizontal scaling. [+] It's the flip side of the vertical-scaling risk in the next section: more machines means no single one taking the whole system down.

traffic over the day morning: 2 nodes peak: nodes added on the fly evening: scaled back
Figure 4 โ€” Elasticity tracks demand: the cloud adds nodes for the peak and returns them afterward, so you pay only for what the traffic needed.
05

Choosing your approach (and the code tax)

Vertical scaling is simpler: no code changes, no complex configuration, far less administration and monitoring than running a distributed environment. Its real downside is availability risk โ€” the servers are powerful but few, so one going down can take the whole site offline. Horizontal scaling avoids that; with many nodes, the system stays highly available.

Dimension Vertical (scale up) Horizontal (scale out)
Effort Simple โ€” no code or config changes Complex โ€” needs stateless code, distributed setup
Limit Hard hardware ceiling Effectively unlimited
Dynamic scaling Not possible Yes โ€” real-time up and down
Availability Risky โ€” few servers, single points of failure High โ€” surviving nodes carry on
Best fit Predictable, non-critical internal tools Public apps with unpredictable traffic

Why the code has to change to run on many machines

Code meant for a distributed environment must be stateless. Concretely, that means no static instances holding state in your classes. Instance variables hold an object's state; static variables hold state spanning many objects, generally per classloader. If the server running that classloader dies, all of that state vanishes and the app is left inconsistent โ€” and static state isn't application-wide to begin with.

The fix is to push state out of the process into a distributed memory store like Redis or Memcached, so state is consistent across the whole application and the components themselves stay stateless. This is why functional programming โ€” whose functions retain no state โ€” fits distributed systems so well, though the same statelessness is achievable in mainstream OOP languages.

โœ• state inside each server Server 1 local state Server 2 local state one crash → its state is gone โœ“ state in shared store Server 1 Server 2 Redis / Memcached shared distributed state
Figure 5 โ€” Statelessness is the code tax of scaling out. Move state into a shared store so any node can serve any request and a crash loses nothing.

So which one?

Start with a ballpark estimate of the traffic your app must handle, then:

[+] In practice most teams now start with a distributed microservices architecture deployed on the cloud, so workloads scale out on the fly by default โ€” vertical scaling has become the exception for small, bounded workloads rather than the norm.

06

Where scalability quietly dies

An app can look well-architected โ€” workload spread across nodes, scaling out cleanly โ€” and still crawl, because a single overlooked component throttles everything behind it. These are the usual choke points.

scaled-out app nodes 1 DB bottleneck → partitioned / sharded across DBs
Figure 6 โ€” The classic bottleneck: a scaled-out app funneling into one monolithic database. The fix is partitioning and sharding across multiple DB servers.
07

Tuning performance so the system scales

Performance and scalability are directly proportional: an app that isn't performant will not scale well, because a performance-optimized system withstands more traffic on fewer resources. These tuning moves can go in even before pre-production testing.

๐Ÿ”ฌ ProfilingRun application and code profilers to find what's slow or resource-hungry. Profiling is dynamic analysis โ€” it measures time and space complexity and surfaces concurrency, memory, and safety issues. Find the bottlenecks, kill them.
โšก CachingCache everywhere and cache wisely. Cache all static content, serve reads from the cache, hit the database only when truly needed. Use a write-through cache.
๐ŸŒ CDNA Content Delivery Network cuts latency further by keeping data physically close to the requesting user.
๐Ÿ—œ๏ธ Data compressionCompress data with apt algorithms and store it compressed. Less bandwidth means faster downloads on the client.
๐Ÿ” Fewer round tripsAvoid unnecessary request-response cycles between client and server. Club multiple requests into one where possible.
๐Ÿ“ˆ ResultEach move lowers application latency, which is what lets the same hardware absorb more concurrent load.
08

Testing for the surge before it arrives

After performance tuning comes capacity planning โ€” provisioning the right amount of compute and storage. There's no universal rule; the right testing approach depends on your system's design, and testing runs at both hardware and software levels, on components individually and together.

What you measure

Scalability testing watches parameters like CPU usage, network bandwidth consumption, throughput, requests processed per unit time, latency, program memory usage, and end-user experience under heavy load.

How it works

App nodes emit metrics cAdvisor Prometheus time-series store Grafana ๐Ÿ‘€ dashed = metrics scraped in ยท solid = data read out to dashboards
Figure 7 โ€” A typical monitoring pipeline: nodes emit metrics, cAdvisor and Prometheus collect and store them, Grafana turns them into the dashboards engineers watch.
09

Recap

Latency is the scoreboardScaling well means latency stays flat as traffic grows โ€” never rises.
Two directionsUp = bigger box, simple but capped. Out = more boxes, unlimited but demands stateless code.
Stateless or bustDistributed code keeps no local/static state; push it to Redis or Memcached.
Elasticity paysThe cloud adds nodes for peaks and removes them after โ€” you pay for what you use, and gain high availability.
Watch the choke pointsSingle DB, sync-everything design, thin caching, bad DB choice, logic in the DB, sloppy code.
Prove it before the surgeProfile, tune, then load-test and monitor with JMeter, Prometheus, Grafana.
๐ŸŽฏ
The single idea underneath it all

Scalability is nothing more than keeping latency constant as load grows. Every technique here โ€” scaling out, going stateless, caching, sharding, elasticity, monitoring โ€” exists to defend that flat line against a rising crowd.

10

Further reading

The external links cited across the section, verified live on 13 Aug 2026.

Real-world scaling for planned surges

[1]
How production engineers support global events on Facebook

Concrete case study of capacity planning for a known traffic spike โ€” how Facebook Live was scaled and load-tested (shadow traffic, synthetic dependency tests) for New Year's Eve. Maps directly onto Section 8.

โš‘ dated โ€” published Feb 2018; the practices hold, the numbers are old

Profiling tools

[2]
List of performance analysis tools (Wikipedia)

A broad catalog of profilers by language and platform โ€” a jumping-off point for the "profile the hell out of your app" step in Section 7.

โš‘ dated / lightly sourced โ€” carries a "needs more citations" banner since 2011; treat as a directory, not authority
๐Ÿ”—
Two cited links couldn't be verified

The section also cited two scaleyourapp.com articles โ€” the author's PolyHaven cost/caching case study and the Hotstar 10M-concurrent-users breakdown. Both returned server errors (HTTP 522) on multiple attempts and are excluded here rather than linked to a broken page. They may simply be temporarily down; worth retrying later. The author's own Cloud Computing 101 and system-design courses on zerotosoftwarearchitect.com were referenced as paid-course promotions and are omitted as not being reading material.