Files
michaelschiemer/src/Framework/RateLimit/MIGRATION.md
Michael Schiemer 55a330b223 Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
2025-08-11 20:13:26 +02:00

8.9 KiB

RateLimit to SlidingWindow Migration Guide

This guide explains how to migrate from the legacy RateLimit implementation to the new SlidingWindow-based system.

Overview

The RateLimit module has been refactored to use the SlidingWindow module for better performance, accuracy, and advanced analytics. The new implementation provides:

  • Improved Accuracy: True sliding window instead of fixed windows
  • Advanced Analytics: Burst detection, threat analysis, and pattern recognition
  • Better Performance: Optimized data structures and caching
  • Unified Architecture: Consistent with other framework modules

Key Changes

1. New Classes

  • SlidingWindowRateLimiter: Modern rate limiter using SlidingWindow
  • SlidingWindowTokenBucket: Token bucket with analytics
  • RateLimitAggregator: Advanced analytics aggregator
  • RateLimitResult: Enhanced result object (already existing)

2. Backwards Compatibility

The old RateLimiter class is still available and functional. No breaking changes to existing API.

Migration Steps

Step 1: Update Dependency Injection

// Old way (still works)
$rateLimiter = $container->get(RateLimiter::class);

// New way (recommended)
$rateLimiter = $container->get(SlidingWindowRateLimiter::class);

// Or use alias
$rateLimiter = $container->get('rate_limiter'); // Points to SlidingWindow version

Step 2: Basic Rate Limiting Migration

// Old implementation
$rateLimiter = new RateLimiter(new CacheStorage($cache));
$result = $rateLimiter->checkLimit('user:123', 10, 60);

// New implementation
$windowFactory = new SlidingWindowFactory($cache);
$rateLimiter = new SlidingWindowRateLimiter($windowFactory);
$result = $rateLimiter->checkLimit('user:123', 10, 60);

// API is identical, but implementation is more accurate

Step 3: Enhanced Analytics (New Feature)

// New advanced analytics capability
$requestContext = [
    'client_ip' => $_SERVER['REMOTE_ADDR'],
    'user_agent' => $_SERVER['HTTP_USER_AGENT'],
    'request_path' => $_SERVER['REQUEST_URI']
];

$result = $rateLimiter->checkLimitWithAnalysis('user:123', 10, 60, $requestContext);

// Check for security threats
if ($result->isAttackSuspected()) {
    // Handle potential attack
    $threatLevel = $result->getThreatLevel(); // 'low', 'medium', 'high', 'critical'
    $patterns = $result->attackPatterns; // ['burst_attack', 'volumetric_attack']
}

// Check for anomalous traffic
if ($result->hasAnomalousTraffic()) {
    $deviation = $result->baselineDeviation;
    // Implement adaptive response
}

Step 4: Token Bucket Migration

// Old token bucket (through RateLimiter)
$result = $rateLimiter->checkTokenBucket('api:service', 100, 10, 5);

// New dedicated token bucket with analytics
$tokenBucket = new SlidingWindowTokenBucket(
    identifier: 'api:service',
    capacity: 100,
    refillRate: 10,
    windowFactory: $windowFactory
);

$result = $tokenBucket->consumeWithAnalysis(5, $requestContext);

Step 5: Update Middleware/Controllers

class RateLimitMiddleware
{
    public function __construct(
        // Old
        // private RateLimiter $rateLimiter
        
        // New
        private SlidingWindowRateLimiter $rateLimiter
    ) {}
    
    public function handle($request, $next)
    {
        $clientId = $this->getClientId($request);
        
        // Enhanced with threat analysis
        $result = $this->rateLimiter->checkLimitWithAnalysis(
            $clientId, 
            100, 
            300, 
            [
                'client_ip' => $request->getClientIp(),
                'user_agent' => $request->getUserAgent(),
                'request_path' => $request->getPath()
            ]
        );
        
        if (!$result->isAllowed()) {
            return $this->createRateLimitResponse($result);
        }
        
        // Log security events
        if ($result->shouldLogSecurityEvent()) {
            $this->logSecurityEvent($result);
        }
        
        return $next($request);
    }
}

Configuration Changes

Environment Variables

No changes to existing environment variables. New optional variables:

# SlidingWindow-specific settings
RATE_LIMIT_PERSISTENT=true
RATE_LIMIT_BURST_THRESHOLD=0.8
RATE_LIMIT_MIN_INTERVAL_THRESHOLD=2.0

# Advanced analytics
RATE_LIMIT_THREAT_ANALYSIS_ENABLED=true
RATE_LIMIT_BASELINE_TRACKING_ENABLED=true

Container Configuration

// In your service provider or bootstrap
$container->bind(SlidingWindowRateLimiter::class, function ($container) {
    $cache = $container->get(Cache::class);
    $windowFactory = new SlidingWindowFactory($cache);
    
    return new SlidingWindowRateLimiter(
        $windowFactory,
        persistent: $_ENV['RATE_LIMIT_PERSISTENT'] ?? true
    );
});

Performance Improvements

Memory Usage

  • Reduced: Optimized data structures in SlidingWindow module
  • Efficient: Smart cleanup of expired data

Processing Speed

  • Faster: Batch operations and optimized algorithms
  • Scalable: Better performance under high load

Accuracy

  • Precise: True sliding window vs. fixed window approximation
  • Consistent: Uniform distribution of requests over time

New Features

1. Burst Detection

$analytics = $rateLimiter->getAdvancedAnalytics('user:123', 60);
if ($analytics['burst_analysis']['burst_detected']) {
    // Handle burst attack
}

2. Threat Analysis

$result = $rateLimiter->checkLimitWithAnalysis($key, $limit, $window, $context);
$threatScore = $result->threatScore->getValue(); // 0-100
$recommendedActions = $result->getRecommendedStrategy();

3. Adaptive Responses

// Automatically adjusts retry-after based on patterns
$retryAfter = $result->adaptiveRetryAfter->toSeconds();

// Multiple response strategies
foreach ($result->responseStrategies as $strategy) {
    match ($strategy) {
        'immediate_block' => $this->blockImmediately(),
        'enhanced_monitoring' => $this->enableMonitoring(),
        'captcha_challenge' => $this->requireCaptcha(),
    };
}

Testing Migration

Unit Tests

class SlidingWindowRateLimiterTest extends TestCase
{
    public function test_basic_rate_limiting()
    {
        $cache = new InMemoryCache();
        $windowFactory = new SlidingWindowFactory($cache);
        $rateLimiter = new SlidingWindowRateLimiter($windowFactory);
        
        // Test basic functionality
        $result = $rateLimiter->checkLimit('test', 5, 60);
        $this->assertTrue($result->isAllowed());
    }
    
    public function test_threat_detection()
    {
        // Test burst pattern detection
        // Test anomaly detection
        // Test attack pattern recognition
    }
}

Integration Tests

class RateLimitIntegrationTest extends TestCase
{
    public function test_middleware_integration()
    {
        // Test with actual HTTP requests
        // Test threat detection in middleware
        // Test performance under load
    }
}

Monitoring and Observability

Metrics to Track

// Basic metrics (existing)
- rate_limit_requests_allowed
- rate_limit_requests_blocked
- rate_limit_processing_time

// New metrics
- rate_limit_threats_detected
- rate_limit_burst_patterns
- rate_limit_baseline_deviations
- rate_limit_adaptive_responses

Logging

// Enhanced logging with threat context
if ($result->shouldLogSecurityEvent()) {
    $logger->warning('Rate limit security event', [
        'client_ip' => $result->clientIp,
        'threat_level' => $result->getThreatLevel(),
        'attack_patterns' => $result->attackPatterns,
        'recommended_actions' => $result->getRecommendedStrategy()
    ]);
}

Rollback Plan

If issues arise, you can easily rollback:

  1. Switch DI binding:

    // Change from
    $container->bind('rate_limiter', SlidingWindowRateLimiter::class);
    // Back to
    $container->bind('rate_limiter', RateLimiter::class);
    
  2. Update middleware: Change constructor injection back to RateLimiter

  3. Remove new features: Comment out threat analysis code

The old implementation remains fully functional and tested.

Timeline

Phase 1: Preparation (Week 1)

  • Update DI container configuration
  • Deploy alongside old implementation
  • Update monitoring

Phase 2: Gradual Migration (Week 2-3)

  • Migrate non-critical endpoints
  • Monitor performance and accuracy
  • Test threat detection

Phase 3: Full Migration (Week 4)

  • Migrate critical endpoints
  • Enable advanced analytics
  • Full monitoring deployment

Phase 4: Optimization (Week 5)

  • Fine-tune threat detection thresholds
  • Optimize performance based on metrics
  • Remove old implementation if stable

Support

For questions or issues during migration:

  1. Check existing unit tests for usage examples
  2. Review the Examples/SlidingWindowRateLimitExample.php file
  3. Consult the SlidingWindow module documentation
  4. Test thoroughly in staging environment

The migration is designed to be gradual and safe, with full backwards compatibility maintained.