System Design · Module 5 · Lesson 1 of 4 · 35 min
Vertical Horizontal and Stateless Application Scaling
Identify the resource bottleneck, compare scaling up with adding instances, and remove private state that prevents safe request reassignment.
01 The idea
The problem this lesson solves
Adding B causes intermittent logouts, while both app health checks stay green.
Prerequisite: earlier lessons introduce the vocabulary and shared examples used here. Follow the module order.
02 Worked example
Follow one worked example
Trace the example in order. Follow the same identities, units and state transitions through the diagram and the events below.
An additional instance helps only when requests can move to it and the constrained resource actually gains capacity.
03 The method
Mechanisms decisions and a guided tutorial
Work through the explanation in order, then apply it in the tutorial. Each comparison names a cost as well as a benefit.
| Choice or concept | Purpose | Boundary or cost |
|---|---|---|
| Vertical scaling | Larger single machine | Resource ceiling and restart risk |
| Horizontal scaling | More instances | State, routing and failure coordination |
| Private durable state | Easy local access | Breaks reassignment |
| Replaceable local cache | Fast reads | Cold instances increase origin load |
Scale up or scale out
Vertical scaling gives one machine more resources. It can be a useful first move when one instance is undersized, but has hardware limits and may require disruption. Horizontal scaling adds instances and distributes work. It can improve capacity and fault tolerance, but creates coordination, routing and deployment complexity. Find the bottleneck first: adding app servers does not increase a saturated database's write capacity.
Move durable state out of app memory
If A keeps a login session only in its own memory, a request routed to B may appear logged out. Use a deliberately designed shared session store or verifiable tokens with appropriate expiry and revocation behavior. Durable uploads belong in shared storage, not one instance's disk. A local cache is acceptable when losing it causes a recoverable miss. Sticky sessions route a client back to an instance, but failure or rescheduling still exposes the private-state problem.
Scale the tier that is constrained
An app may be CPU-bound, waiting for a database, blocked on a lock or limited by a remote API. Adding app instances helps some of these cases and can worsen others. More callers can increase contention at the same saturated database. Start with where time and queues accumulate, then predict how the proposed change affects that resource.
Vertical scaling often preserves operational simplicity but has a ceiling and can require disruption. Horizontal scaling can add capacity and redundancy, but brings routing, deployment and state-ownership work. Neither choice is automatically more professional; the requirements and measured bottleneck determine the useful move.
Classify state by recoverability
In-flight request variables belong in memory. A local cache may also be private if losing it causes a recoverable miss. A login session, uploaded file or accepted business record that must survive reassignment needs a deliberate shared or durable home.
With local session files, a user can appear logged out when the next request reaches another healthy server. Sticky routing may hide the symptom until a restart or failover. A shared session store or verifiable token design addresses different trade-offs around revocation, expiry and availability; spell out that contract rather than call all state “stateless.”
Test reassignment before claiming elasticity
Start a request on A, route the next to B and remove A. The user action should still work under the stated contract. Also test uploads, background jobs and idempotency records: these are frequent private-state leaks.
An extra replica must be initialized and ready before receiving traffic. Warm necessary data gradually and ensure the shared cache and database can support the larger pool. A scaling event changes connection count and cache behavior even if the application code is unchanged.
Guided tutorial
1. List state
Inventory session data, uploads, local caches, jobs and accepted operations.
2. Label recovery
Mark each item as disposable, reconstructible or durable.
3. Move one request
Trace two requests from one user reaching different instances.
4. Identify the bottleneck
Choose a measurement that would justify app scaling instead of database work.
request state: private, short-lived
local cache: replaceable, misses are recoverable
session / accepted work: explicit shared or durable authority
upload: durable object storage or another shared contract
scale decision: measured bottleneck + surviving capacity04 Cheat sheet
Review the decisions
Use this table to explain the mechanism and its limit without memorizing a product name.
| Choice or concept | Remember | Check |
|---|---|---|
| Vertical scaling | Larger single machine | Resource ceiling and restart risk |
| Horizontal scaling | More instances | State, routing and failure coordination |
| Private durable state | Easy local access | Breaks reassignment |
| Replaceable local cache | Fast reads | Cold instances increase origin load |
05 Where & why
Check the primary references
Use official references for protocol and implementation details. The questions here are teaching prompts.
06 Interview questions
Explain the reasoning out loud
Answer before opening the explanation. The questions progress from vocabulary to decisions and failure behavior.
What does Vertical scaling mean?
What does Horizontal scaling mean?
What does Stateless request handling mean?
Does stateless mean the process has no memory?
Why can more instances hurt a database-bound service?
Are sticky sessions a complete recovery plan?
When is vertical scaling reasonable?
What should a reassignment test include?
07 Practice problems
Practice a new case
Solve the new cases before revealing hints. Complete worked solutions follow the set.
Choose the direction
EasyShow the hint
Find the state
EasyShow the hint
Resource diagnosis
MediumShow the hint
State classification
MediumShow the hint
Failover trace
MediumShow the hint
Scaling proposal
HardShow the hint
Worked solutions
1. Choose the direction
More CPU is vertical scaling; another instance with routing is horizontal scaling.
2. Find the state
The second instance cannot read the first instance's private session file. Store session state in a shared service or use a suitable verifiable-token design, with explicit expiry and revocation behavior.
3. Resource diagnosis
The constrained resource is coordinated database work. More app concurrency can amplify waiting; inspect the transaction/query pattern and bound demand first.
4. State classification
The buffer is transient; the thumbnail cache can be replaceable if regeneration is safe; an accepted job record needs durable ownership and recovery.
5. Failover trace
The upload needs a shared durable location or explicit ownership/routing and recovery design. A healthy second app cannot read A’s private disk automatically.
6. Scaling proposal
Measure latency, throughput, connection count, cache misses and database saturation at increasing app counts under the same workload. Include one-instance loss and cold starts before claiming the target is met.