Adding Machines
Horizontal scaling means adding more machines to handle increased load.
How Horizontal Scaling Works
Before (2 servers):
┌─────────────┐ ┌─────────────┐
│ Server 1 │ │ Server 2 │
│ (handling │ │ (handling │
│ 500 RPS) │ │ 500 RPS) │
└──────┬──────┘ └──────┬──────┘
└────────┬──────────┘
│
Total: 1000 RPS
After (4 servers):
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ Server 1 │ │ Server 2 │ │ Server 3 │ │ Server 4 │
│ (250 RPS)│ │ (250 RPS)│ │ (250 RPS)│ │ (250 RPS)│
└────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
└────────────┴────────────┴────────────┘
│
Total: 1000 RPS
Requirements for Horizontal Scaling
1. Stateless Services
- No session data on server
- Externalize state (Redis, DB)
2. Load Balancer
- Distribute traffic
- Health checks
3. Shared Storage
- Same data accessible from all servers
- Database, cache, file storage
4. No Server Affinity
- Any request can go to any server
- Sticky sessions (if needed)
Scaling Web Servers
Web Tier Scaling:
1. Add new server
2. Install application
3. Configure to connect to shared resources
4. Add to load balancer pool
5. Verify health checks pass
6. Monitor performance
Auto-scaling:
- CPU > 70% → Add server
- CPU < 30% → Remove server
Scaling Considerations
| Factor | Consideration |
|---|---|
| State | Externalize to Redis/DB |
| Sessions | Use sticky sessions or external store |
| Files | Use shared storage (S3, NFS) |
| Cache | Distributed cache (Redis Cluster) |
| Database | Read replicas, sharding |
Load Distribution
Effective load distribution ensures all servers are utilized evenly.
Distribution Strategies
1. Even Distribution
Each server gets equal traffic
Server 1: 250 RPS
Server 2: 250 RPS
Server 3: 250 RPS
Server 4: 250 RPS
2. Weighted Distribution
More powerful servers get more traffic
Server 1 (powerful): 400 RPS
Server 2 (medium): 300 RPS
Server 3 (small): 200 RPS
3. Capability-Based
Route based on server capabilities
GPU servers → ML workloads
CPU servers → General workloads
Memory servers → In-memory processing
Load Balancer Configuration
upstream web_servers {
# Round Robin (default)
server 10.0.0.1:8080;
server 10.0.0.2:8080;
server 10.0.0.3:8080;
# Weighted
server 10.0.0.1:8080 weight=5; # Powerful
server 10.0.0.2:8080 weight=3; # Medium
server 10.0.0.3:8080 weight=2; # Small
# Backup
server 10.0.0.4:8080 backup; # Failover
}
Load Distribution Monitoring
Monitor:
- Requests per server
- Response time per server
- Error rate per server
- Connection count per server
Alert if:
- Uneven distribution (>20% variance)
- High error rate on specific server
- Server health check failures
Scaling Database Tier
Database Scaling Options:
1. Read Replicas
Primary → Replica 1, Replica 2, Replica 3
Reads go to replicas, writes to primary
2. Connection Pooling
Servers share pool of DB connections
Reduce connection overhead
3. Caching Layer
Redis/Memcached in front of database
Reduce database load
4. Sharding
Data split across multiple databases
Each shard handles subset of data
Session Management
Managing user sessions in a scaled environment requires careful design.
Session Options
1. Sticky Sessions (Session Affinity)
Client → Server A (all requests)
Problem: Server failure loses session
Solution: Backup sessions or external store
2. External Session Store
Client → Any Server → Redis → Session Data
All servers access same session store
3. Database Session Store
Client → Any Server → Database → Session Data
Persistent but slower
4. JWT ( Stateless)
Client → Any Server → Decode Token → Session Data
No server-side storage needed
Sticky Sessions Implementation
# Nginx IP Hash
upstream backend {
ip_hash;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
}
# Nginx Cookie-based
upstream backend {
hash $cookie_jsessionid consistent;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
}
External Session Store (Redis)
// Express.js example
const session = require('express-session');
const RedisStore = require('connect-redis').default;
const redis = require('redis');
const client = redis.createClient();
app.use(session({
store: new RedisStore({ client }),
secret: 'your-secret',
resave: false,
saveUninitialized: false
}));
// Session stored in Redis
// All servers can access same sessions
JWT for Stateless Sessions
1. User logs in
Server creates JWT with user data
2. JWT returned to client
Client stores in cookie or header
3. Subsequent requests
Client sends JWT in Authorization header
4. Server validates JWT
No database lookup needed
Benefits:
- No server-side storage
- Scalable (any server can handle)
- Fast (no DB lookup)
Tradeoffs:
- Larger request size
- Can't revoke until expiry
- Limited data storage
Session Management Best Practices
- Externalize session data: Don't store on application server
- Use appropriate TTL: Sessions should expire
- Secure session storage: Encrypt sensitive data
- Monitor session storage: Redis memory usage
- Plan for failover: Session data must survive server failures
Practice Problems
Design a scalable Horizontal Scaling system. Cover high-level architecture, data model, and API design.
Solution
// Complete system design:
// - Functional + Non-functional requirements
// - Capacity estimation
// - Data model (SQL/NoSQL choice)
// - API endpoints
// - Component architecture
// - Scaling strategy
// - Monitoring & reliabilityHow would you scale Horizontal Scaling to handle 10x the current load? Identify bottlenecks and solutions.
Solution
// Scaling approach:
// 1. Load balancing
// 2. Database sharding/replication
// 3. Cache layer (Redis)
// 4. CDN for static assets
// 5. Async processing (queues)
// 6. Microservices decompositionAnalyze potential failure modes for Horizontal Scaling and design mitigation strategies.
Solution
// Failure mitigation:
// 1. Redundancy (multi-AZ)
// 2. Circuit breakers
// 3. Retry with backoff
// 4. Dead letter queues
// 5. Health checks
// 6. Graceful degradationQuiz
1. What is the key requirement for horizontal scaling?
2. How do you handle sessions when scaling horizontally?
3. What is the advantage of weighted load balancing?
4. Why is externalizing state important for horizontal scaling?
Flashcards
Question
What is horizontal scaling?
Click to reveal answer
Answer
Adding more machines to increase capacity. Requires: stateless services, load balancer, shared storage, no server affinity.
Question
How do you handle sessions in a horizontally scaled system?
Click to reveal answer
Answer
Externalize sessions to Redis or use JWT tokens. Sticky sessions are an alternative but less flexible. All servers access the same session store.
Question
What is weighted load balancing?
Click to reveal answer
Answer
Distributing traffic proportionally based on server capacity. More powerful servers get more traffic. Used for heterogeneous server fleets.
Question
What is the difference between sticky sessions and external session store?
Click to reveal answer
Answer
Sticky sessions route same client to same server (session on server). External store (Redis) keeps sessions centrally, allowing any server to handle requests.
Question
What is Horizontal Scaling?
Click to reveal answer
Answer
Horizontal Scaling is a key concept in system design.
Revision Notes
Key Takeaways
- 1.Horizontal scaling requires stateless services and shared storage
- 2.Load balancers distribute traffic across multiple servers
- 3.Sessions must be externalized (Redis) or use JWT
- 4.Weighted distribution accounts for different server capacities
- 5.Monitor distribution and health for reliable scaling
Interview Tips
- •Always discuss how you'll handle sessions when scaling horizontally
- •Mention Redis or external session store as best practice
- •Consider auto-scaling based on load metrics
- •Discuss database scaling alongside application scaling
Cheat Sheet
Horizontal Scaling - Cheat Sheet
Requirements:
- Stateless services
- Load balancer
- Shared storage
- No server affinity
Load Distribution:
- Even: Same traffic to all
- Weighted: Based on capacity
- Capability-based: Route by capability
Session Options:
| Option | Pros | Cons |
|---|---|---|
| Sticky sessions | Simple | Server failure risk |
| Redis store | Flexible | Extra dependency |
| JWT | Stateless | Can't revoke early |
Scaling Steps:
- Add new server
- Install app
- Configure shared resources
- Add to load balancer
- Verify health checks
- Monitor