When to Shed Load
When to Shed Load
Load shedding drops requests when system is overloaded to protect core functionality.
When to Shed
1. CPU/Memory Near Limit:
CPU > 90%
Memory > 85%
2. Queue Depth High:
Queue > threshold
Processing lag increasing
3. Latency Spike:
Response time > SLA
Timeout rate increasing
4. Error Rate High:
Error rate > threshold
Cascading failures
5. Downstream Degraded:
Dependency slow/failed
Circuit breaker open
Decision Matrix
| Metric | Normal | Warning | Shed |
|---|---|---|---|
| CPU | < 70% | 70-90% | > 90% |
| Memory | < 70% | 70-85% | > 85% |
| Latency P99 | < 100ms | 100-500ms | > 500ms |
| Error Rate | < 1% | 1-5% | > 5% |
| Queue Depth | < 1000 | 1000-5000 | > 5000 |
Implementation
class LoadShedder:
def __init__(self, thresholds):
self.thresholds = thresholds
def should_shed(self, metrics):
for metric, value in metrics.items():
if metric in self.thresholds:
if value > self.thresholds[metric]['shed']:
return True
return False
def get_shed_percentage(self, metrics):
"""Calculate what percentage to shed"""
max_overload = 0
for metric, value in metrics.items():
if metric in self.thresholds:
shed_threshold = self.thresholds[metric]['shed']
overload = (value - shed_threshold) / shed_threshold
max_overload = max(max_overload, overload)
return min(max_overload, 1.0) # Max 100% shed
Shedding Response
def shed_request():
return Response(
status=503,
body={'error': 'Service temporarily overloaded'},
headers={'Retry-After': '30'}
)
Priority-Based Shedding
Priority-Based Shedding
Priority Levels
Priority Levels:
1. Critical (must serve):
- Health checks
- Core transactions
- Paying customers
2. High (prefer to serve):
- Authenticated users
- Important operations
3. Medium (nice to serve):
- Regular requests
- Non-critical reads
4. Low (shed first):
- Analytics
- Background jobs
- Non-essential features
Implementation
class PriorityLoadShedder:
def __init__(self):
self.priorities = {
'critical': 0, # Never shed
'high': 0.2, # Shed up to 20%
'medium': 0.5, # Shed up to 50%
'low': 1.0 # Shed up to 100%
}
def should_shed(self, priority, load_level):
"""Check if request should be shed"""
if priority == 'critical':
return False
shed_threshold = self.priorities[priority]
return load_level > shed_threshold
def get_priority(self, request):
"""Determine request priority"""
if request.headers.get('X-Priority') == 'critical':
return 'critical'
if request.user and request.user.is_premium:
return 'high'
if request.method in ['GET', 'HEAD']:
return 'medium'
return 'low'
Priority Configuration
load_shedding:
priorities:
critical:
threshold: 0.95 # Only shed at 95% overload
high:
threshold: 0.8
medium:
threshold: 0.6
low:
threshold: 0.4
rules:
- match: path=/health
priority: critical
- match: user.premium=true
priority: high
- match: method=GET
priority: medium
Adaptive Shedding
class AdaptiveShedder:
def __init__(self):
self.metrics_history = []
def calculate_shed_rate(self):
"""Adapt shed rate based on metrics"""
recent = self.metrics_history[-100:]
avg_latency = sum(r['latency'] for r in recent) / len(recent)
error_rate = sum(1 for r in recent if r['error']) / len(recent)
if error_rate > 0.1: # 10% errors
return 0.5 # Shed 50%
elif avg_latency > 1000: # 1 second
return 0.3 # Shed 30%
else:
return 0 # Don't shed
Implementation
Load Shedding Implementation
Middleware Implementation
class LoadSheddingMiddleware:
def __init__(self, app, load_shedder):
self.app = app
self.shedder = load_shedder
def __call__(self, environ, start_response):
# Check load
metrics = self.get_current_metrics()
if self.shedder.should_shed(metrics):
# Shed request
response = Response(
status=503,
body='Service temporarily overloaded',
headers={'Retry-After': '30'}
)
return response(environ, start_response)
# Process normally
return self.app(environ, start_response)
Load Shedding at Different Levels
1. Load Balancer Level:
- Shed at edge
- Protect entire service
- Fast, simple
2. API Gateway Level:
- Route-based shedding
- Rate limiting integration
- More granular
3. Application Level:
- Feature-based shedding
- Priority-based
- Most granular
4. Database Level:
- Query rejection
- Connection limits
- Protect data layer
Monitoring
def monitor_load_shedding():
metrics = {
'shed_count': get_shed_count(),
'shed_rate': get_shed_rate(),
'load_level': get_load_level(),
'priority_distribution': get_priority_distribution()
}
if metrics['shed_rate'] > 0.1: # 10%
alert('High load shedding rate')
metrics.gauge('load_shedding.rate', metrics['shed_rate'])
metrics.counter('load_shedding.count', metrics['shed_count'])
Best Practices
- Shed early (at edge, not deep in stack)
- Use priority-based shedding
- Return 503 with Retry-After
- Monitor shed rates
- Test under load
- Have fallback for shed requests
Practice Problems
Design a scalable Load Shedding 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 Load Shedding 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 Load Shedding 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. When should you shed load?
2. What HTTP status code for shed requests?
3. Why use priority-based shedding?
4. Where should load shedding happen?
5. What should shed requests return?
Flashcards
Question
When to shed load?
Click to reveal answer
Answer
When CPU > 90%, memory > 85%, latency spikes, error rates high, or downstream degraded
Question
Priority-based shedding?
Click to reveal answer
Answer
Critical (never shed), High (shed 20%), Medium (shed 50%), Low (shed 100%)
Question
HTTP response for shed requests?
Click to reveal answer
Answer
503 Service Unavailable with Retry-After header indicating when to retry
Question
Where to implement load shedding?
Click to reveal answer
Answer
At the edge (load balancer/API gateway) to protect the entire stack from overload
Question
Why shed load?
Click to reveal answer
Answer
To protect core functionality from cascading failures when system is overloaded
Revision Notes
Key Takeaways
- 1.Shed load when system is overloaded to protect core functionality
- 2.Use priority-based shedding to protect critical requests
- 3.Return 503 with Retry-After for shed requests
- 4.Shed at the edge (load balancer/API gateway)
- 5.Monitor shed rates and test under load
Interview Tips
- •Explain when to trigger load shedding
- •Discuss priority-based shedding strategy
- •Mention shedding at the edge vs deep in stack
- •Give examples of what to shed first
Cheat Sheet
Cheat Sheet: Load Shedding
When to Shed
- CPU > 90%
- Memory > 85%
- Latency spike
- Error rate high
- Downstream degraded
Priority Levels
- Critical: Never shed
- High: Shed 20%
- Medium: Shed 50%
- Low: Shed 100%
Response
- 503 Service Unavailable
- Retry-After header
Implementation
- Shed at edge
- Priority-based
- Monitor shed rates