Skip to content
intermediatePhase 48 · Distributed Systems

Load Shedding

Drop excess requests to maintain system stability under heavy load.

30m
0 problems
Topic Progress0%

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

  1. Shed early (at edge, not deep in stack)
  2. Use priority-based shedding
  3. Return 503 with Retry-After
  4. Monitor shed rates
  5. Test under load
  6. Have fallback for shed requests

Practice Problems

0/3solved
Design Load Shedding System

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 & reliability
Load Shedding Scaling

How 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 decomposition
Load Shedding Failure Modes

Analyze 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 degradation

Quiz

1. When should you shed load?

Question 1 options

2. What HTTP status code for shed requests?

Question 2 options

3. Why use priority-based shedding?

Question 3 options

4. Where should load shedding happen?

Question 4 options

5. What should shed requests return?

Question 5 options

Flashcards

Question

When to shed load?

Answer

When CPU > 90%, memory > 85%, latency spikes, error rates high, or downstream degraded

Question

Priority-based shedding?

Answer

Critical (never shed), High (shed 20%), Medium (shed 50%), Low (shed 100%)

Question

HTTP response for shed requests?

Answer

503 Service Unavailable with Retry-After header indicating when to retry

Question

Where to implement load shedding?

Answer

At the edge (load balancer/API gateway) to protect the entire stack from overload

Question

Why shed load?

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