Intermediate System design concept · Handling Scale & Bottlenecks · 22 mins read
Scaling Systems
Choosing between a bigger machine and more machines is the first scaling fork.
Horizontal Scaling
Add more identical application instances to handle more traffic without relying on one ever-bigger machine.
Intuition
A single server can only grow so far before CPU, memory, network, or maintenance windows become the bottleneck. When traffic spikes, one oversized box also concentrates failure risk in one place. Horizontal scaling is the default way modern web tiers survive growth, bursts, and failures. Interviewers care because it forces you to explain statelessness, load balancing, shared state, and why scaling compute is easier than scaling a primary database.
Mental Model
Vertical scaling means making one machine bigger. Horizontal scaling means making many machines interchangeable so a load balancer can spread requests across them. That only works cleanly when app instances do not depend on local in-memory session or file state; otherwise adding servers just creates inconsistency. Think of it like: A restaurant can either buy one giant oven or add more cooking stations. More stations help only if any chef can prepare any order from shared ingredients instead of each station hiding its own private pantry.
Building Blocks
- Interchangeable app instances behind one stable endpoint. Any instance should be able to serve the same request shape, so scaling adds capacity instead of special cases.
- A load balancer with health checks. It spreads traffic across the fleet and removes bad instances before they keep hurting users.
- Externalized state such as Redis sessions and object storage. Once state stops living on one box, users can move between instances safely.
- Autoscaling tied to demand signals like request rate, queue depth, or latency. It matters only if new instances can start fast enough to help during a spike.
Definitions
- Horizontal Scaling
-
Adding more servers and sharing traffic across them so total capacity grows with instance count.
- It improves both throughput and fault tolerance at the app tier.
- It works best when servers are interchangeable.
- Stateless Service
-
A service whose next request can be handled by any healthy instance because important state is stored elsewhere.
- Local memory or disk should not be required for user continuity.
- Statelessness is the main enabler for clean scale-out.
- Load Balancer
-
The entry point that forwards requests to one backend from a pool of healthy backends.
- It hides server churn from clients behind one stable address.
- It is what makes many instances feel like one service.
- Autoscaling
-
Automatically changing the number of instances based on measured demand or pressure.
- It absorbs normal traffic variation without manual intervention.
- It does not fix slow code or a saturated database.
Patterns
- Scale the stateless web or API tier first; it is usually the easiest place to add more capacity safely.
- Move sessions, uploads, and long-running work out of the instance before adding more servers.
- Keep one stable front door so instances can be added or removed without changing clients.
Strategies
- Externalize the blockers to scale-out first: sessions to Redis, files to object storage, and background work to queues.
- Scale on demand signals that map to user pain, such as sustained latency or queue depth, not CPU alone.
- Check downstream limits before celebrating a larger fleet, because the bottleneck often shifts to the database or another dependency.
The real prerequisite for horizontal scaling
Adding servers is easy; making them interchangeable is the hard part. If login state, uploads, or workflow progress live only on one instance, the load balancer cannot freely move requests and the extra servers add inconsistency instead of resilience.
That is why horizontal scaling is really an application-design choice, not just an infrastructure choice. Once the service is stateless at the request path, a load balancer can spread traffic, health checks can remove bad nodes, and autoscaling can add capacity without breaking user flows.
The common failure mode is scaling the app tier while leaving a shared dependency unchanged. If every new server doubles traffic to the same primary database, the architecture did scale, but only one layer did.
Tradeoffs
- Compared with vertical scaling, scale-out gives elasticity and redundancy, but it adds more moving parts and network hops.
- Externalized state enables interchangeable servers, but it introduces new dependencies whose latency and availability now matter.
- Autoscaling saves cost during quiet periods, but poor thresholds can scale too late or flap during noisy traffic.
Real World
- Netflix keeps web and API tiers horizontally scalable so instance failures and traffic bursts are absorbed by fleets instead of one oversized server.
- Shopify adds application capacity during flash-sale events while keeping shared state outside the app node so any healthy instance can serve the next request.
Interview
Questions interviewers ask
- Why does horizontal scaling usually require stateless application servers?
- What breaks if session data stays only in local memory?
- Why do horizontally scaled services still need a load balancer?
- How do you know whether the app tier or a downstream dependency is the real bottleneck?
What a strong answer covers
Candidates should contrast scale-up with scale-out, explain statelessness as the key prerequisite, mention shared state stores, and note that new app servers often move the bottleneck downstream rather than removing it.
Common traps
- Saying "just add servers" without explaining where sessions, files, or other sticky state live.
- Treating autoscaling as a cure for slow queries or overloaded downstream systems.
- Forgetting that one stable entry point and health-aware routing are part of the pattern.
Quiz
What is the main architectural precondition for scaling an application tier horizontally?
- Using a larger VM type
- Keeping the service stateless or moving state outside the instance
- Running on bare metal only
- Using SQL instead of NoSQL
If requests depend on local instance memory or disk, adding more servers creates inconsistent behavior. Horizontal scaling works cleanly when any instance can handle any request.
Why is a load balancer typically placed in front of horizontally scaled app servers?
- To distribute traffic across healthy instances behind one stable endpoint
- To make every request strongly consistent
- To replace the database primary
- To eliminate all network latency
The load balancer hides backend churn from clients and spreads requests across the server pool. Without it, clients would need to track instance addresses and failures themselves.
Which statement best describes vertical scaling?
- Adding more instances behind a dispatcher
- Splitting the database into shards
- Moving sessions into Redis
- Making one machine bigger by adding more CPU, RAM, or bandwidth
Vertical scaling upgrades one node instead of increasing node count. It is simple, but it has cost and hardware ceilings.
An app stores login sessions only in process memory. What is the biggest risk after adding more app instances?
- TLS will stop working
- The load balancer cannot perform health checks
- Users may appear logged out when their next request lands on a different server
- CPU usage will always decrease
Local-only session state ties a user to one machine. Once requests spread across multiple servers, follow-up requests may miss the in-memory session entirely.
What is the best way to think about autoscaling?
- A replacement for performance tuning
- A way to reduce the need for monitoring
- A mechanism to adjust instance count to changing load
- A guarantee that the database will never bottleneck
Autoscaling adds or removes capacity as demand changes. It helps with elastic load, but it does not fix inefficient code or slow downstream systems.
Load Balancer vs Reverse Proxy
Learn which edge responsibilities belong to a reverse proxy, which belong to load balancing, and why one product can play both roles.
This section is part of the full PRISM roadmap, with worked examples, trade-off tables, interview questions and a quiz.
Unlock the full lessonL4 vs L7 Load Balancing
Compare transport-layer and application-layer load balancing so you know when fast connection routing is enough and when HTTP awareness is required.
This section is part of the full PRISM roadmap, with worked examples, trade-off tables, interview questions and a quiz.
Unlock the full lessonPractice scaling systems in PRISM
Concepts stick when you watch them fail. Build an architecture that depends on scaling systems, push traffic through it in the PRISM simulator, and see the latency and error rates change as you adjust the design.