Horizontal vs Vertical Scaling
Scaling Models
Vertical (Scale Up) Horizontal (Scale Out)
┌──────────────┠┌──────┠┌──────â”
│ Bigger CPU │ │Node 1│ │Node 2│
│ More RAM │ vs └──────┘ └──────┘
│ Faster Disk │ ┌──────┠┌──────â”
└──────────────┘ │Node 3│ │Node 4│
└──────┘ └──────┘
| Aspect | Vertical | Horizontal |
|---|---|---|
| Cost | Expensive at scale | Linear cost |
| Limit | Hardware limit | Theoretically unlimited |
| Complexity | Low | High |
| Downtime | Required for upgrades | Zero-downtime |
| Failure impact | Single point of failure | Distributed risk |
When to Scale Horizontally
- Traffic exceeds single node capacity
- Need zero-downtime deployments
- Require geographic distribution
- Need fault tolerance
// Magento web node configuration
// app/etc/env.php
'deployment' => [
'default' => [
'cron_run' => true,
'content_region' => 'default'
]
],
Load Balancer Configuration
Load Balancer Algorithms
Round Robin: A→1, B→2, C→3, D→1, E→2...
Least Connect: Route to server with fewest connections
IP Hash: Hash(client IP) → server index
Weighted: Server 1 (weight 3), Server 2 (weight 1)
NGINX Load Balancer Config
upstream magento_backend {
least_conn;
server web1.example.com:8080 weight=5;
server web2.example.com:8080 weight=5;
server web3.example.com:8080 backup;
keepalive 32;
}
server {
listen 443 ssl http2;
server_name store.example.com;
location / {
proxy_pass http://magento_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 30s;
proxy_read_timeout 60s;
}
}
HAProxy Configuration
frontend magento_https
bind *:443 ssl crt /etc/ssl/magento.pem
default_backend magento_nodes
backend magento_nodes
balance leastconn
option httpchk GET /health_check.php
server web1 10.0.1.10:8080 check inter 5s fall 3 rise 2
server web2 10.0.1.11:8080 check inter 5s fall 3 rise 2
server web3 10.0.1.12:8080 check backup
Session Sharing Across Nodes
Shared Session Storage Options
┌─────────────┠┌──────────────â”
│ Web Node 1 │────▶│ │
└─────────────┘ │ Redis / │
┌─────────────┠│ Memcached │
│ Web Node 2 │────▶│ │
└─────────────┘ │ (Shared) │
┌─────────────┠│ │
│ Web Node 3 │────▶│ │
└─────────────┘ └──────────────┘
Redis Session Configuration
// app/etc/env.php
'session' => [
'save' => 'redis',
'redis' => [
'host' => 'redis-cluster.example.com',
'port' => '6379',
'password' => '',
'timeout' => '2.5',
'persistent_identifier' => '',
'database' => '0',
'compression_threshold' => '2048',
'compression_library' => 'zstd',
'log_level' => '1',
'max_concurrency' => '6',
'break_after_frontend' => '5',
'break_after_adminhtml' => '30',
'first_lifetime' => '600',
'bot_first_lifetime' => '60',
'disable_locking' => '0',
'min_lifetime' => '60',
'max_lifetime' => '2592000'
]
],
Memcached Session Configuration
'session' => [
'save' => 'memcached',
'save_path' => 'memcached-cluster:11211?persistent=1&weight=1&timeout=1&retry_interval=15'
],
Sticky Sessions
Sticky Session Strategies
Without Sticky Sessions: With Sticky Sessions:
Request 1 → Node A (session) Request 1 → Node A (session)
Request 2 → Node B (MISS!) Request 2 → Node A (HIT)
Request 3 → Node C (MISS!) Request 3 → Node A (HIT)
NGINX Sticky Sessions
upstream magento_backend {
sticky cookie srv_id expires=1h domain=.example.com path=/;
server web1.example.com:8080;
server web2.example.com:8080;
}
HAProxy Sticky Sessions
backend magento_nodes
balance roundrobin
cookie SERVERID insert indirect nocache
server web1 10.0.1.10:8080 cookie web1
server web2 10.0.1.11:8080 cookie web2
Trade-offs
| Pros | Cons |
|---|---|
| Simple session handling | Uneven load distribution |
| No shared storage needed | Node failure loses sessions |
| Lower latency | Difficult node maintenance |
Recommendation
- Use shared Redis/Memcached sessions over sticky sessions
- Sticky sessions are a workaround, not a solution
- Shared sessions enable true horizontal scaling
Quiz
1. What is the main advantage of horizontal over vertical scaling?
2. What algorithm routes requests to the server with fewest connections?
3. Why are shared sessions preferred over sticky sessions?
Flashcards
Question
Horizontal vs vertical scaling?
Click to reveal answer
Answer
Horizontal adds nodes (scale out), vertical upgrades hardware (scale up)
Question
Least Connections algorithm?
Click to reveal answer
Answer
Routes request to server with fewest active connections
Question
Sticky sessions trade-off?
Click to reveal answer
Answer
Simple but causes uneven load distribution and session loss on node failure
Question
Best session strategy for scaling?
Click to reveal answer
Answer
Shared Redis/Memcached sessions across all nodes
Revision Notes
Key Takeaways
- 1. Horizontal scaling adds nodes for unlimited capacity
- 2. Load balancers distribute traffic across web nodes
- 3. Shared Redis/Memcached enables sessions across nodes
- 4. Sticky sessions are a workaround, not ideal for scaling
- 5. NGINX and HAProxy support both load balancing and sticky sessions
Interview Tips
- • Compare horizontal vs vertical scaling trade-offs
- • Explain load balancer algorithms and when to use each
- • Discuss session sharing strategies in distributed systems
Cheat Sheet
Horizontal Scaling:
Scale out: add more nodes
Requires: load balancer + shared sessions
Load Balancers:
Round Robin: Even distribution
Least Conn: Best for variable request times
IP Hash: Sticky by IP
Weighted: unequal node capacity
Session Sharing:
Redis: Fast, persistent, supports clustering
Memcached: Simple, in-memory only
Sticky sessions: Quick fix, not ideal