Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Rate Limiter Laravel Package

symfony/rate-limiter

Symfony Rate Limiter component implementing token bucket rate limiting. Configure limiters via a factory and use reserve() to wait for tokens or consume() to attempt immediately. Supports pluggable storage like in-memory for controlling request/input/output rates.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Token Bucket Algorithm: Aligns with Laravel’s existing throttle middleware (Symfony’s RateLimiter is its upstream dependency), ensuring consistency in behavior and debugging.
  • Pluggable Storage: Supports InMemoryStorage (for single-instance Laravel apps), RedisStorage, or custom backends, fitting Laravel’s caching layer (Redis, database, file).
  • Non-Blocking vs. Blocking: consume() (non-blocking) integrates with Laravel’s middleware pipeline, while reserve()->wait() can be used in CLI/queue workers (e.g., Laravel Horizon).
  • Compound Policies: CompoundRateLimiterFactory enables complex rules (e.g., "limit to 100 requests/hour and 10 requests/minute"), useful for multi-tenant SaaS.
  • HTTP Compliance: Automatically generates Retry-After headers (RFC 6585), reducing client-side retry logic in APIs.

Key Misalignment:

  • Laravel’s built-in throttle middleware already uses Symfony’s RateLimiter under the hood. This package is redundant for basic API rate limiting unless you need:
    • Custom storage backends (e.g., DynamoDB, custom database tables).
    • Compound rate limits (e.g., per-IP and per-user).
    • Non-HTTP rate limiting (e.g., queue jobs, CLI commands).

Integration Feasibility

  • Laravel Compatibility:
    • Works with Laravel 10+ (Symfony 6.4+) and Laravel 11+ (Symfony 7.0+).
    • Integrates with Laravel’s Cache facade (Redis, database, file) via CacheStorage.
    • Supports Laravel’s throttle middleware out of the box (no rewrite needed).
  • Dependency Conflicts:
    • Requires Symfony’s options-resolver and contracts (already bundled with Laravel).
    • No conflicts with Laravel’s core or popular packages (e.g., spatie/laravel-rate-limiting is a wrapper for this).
  • Configuration:
    • Can be configured via config/rate_limits.php or environment variables (e.g., .env).
    • Example:
      'rate_limits' => [
          'login' => [
              'policy' => 'token_bucket',
              'limit' => 5,
              'interval' => '5 minutes',
          ],
      ],
      
  • Middleware Integration:
    • Replace or extend Laravel’s throttle middleware:
      use Symfony\Component\RateLimiter\RateLimiterFactory;
      use Symfony\Component\RateLimiter\Storage\CacheStorage;
      
      $factory = new RateLimiterFactory([
          'id' => 'api',
          'policy' => 'token_bucket',
          'limit' => 100,
          'interval' => '1 hour',
      ], new CacheStorage(app('cache')));
      
      $limiter = $factory->create();
      if (!$limiter->consume(1)->isAccepted()) {
          abort(429, 'Too many requests');
      }
      

Technical Risk

Risk Mitigation Severity
Distributed Storage Redis/Memcached required for multi-instance Laravel (e.g., Kubernetes). High
PHP 8.1+ Requirement Laravel 10+ enforces PHP 8.1+, so no risk for modern stacks. Low
Token Bucket Complexity Debugging retryAfter or reserve() logic may require Symfony docs. Medium
Storage Backend Limits InMemoryStorage is single-instance only; Redis required for scaling. High
Middleware Overhead Non-blocking consume() adds minimal latency (~1ms for Redis). Low
Compound Limits CompoundRateLimiterFactory adds complexity; test thoroughly in staging. Medium

Critical Questions for TPM:

  1. Is multi-instance rate limiting required?
    • If yes, Redis/Memcached is mandatory (not optional).
    • If no, InMemoryStorage or database-backed CacheStorage suffices.
  2. Will we use compound limits (e.g., per-IP + per-user)?
    • Requires CompoundRateLimiterFactory and careful testing.
  3. How will we configure limits dynamically?
    • Environment variables? Database? Feature flags?
  4. Do we need to support non-HTTP rate limiting (e.g., queues, CLI)?
    • reserve()->wait() is ideal for blocking operations (e.g., Laravel Horizon jobs).
  5. What’s our fallback for storage failures?
    • Example: Use CacheStorage with a fallback to InMemoryStorage.

Integration Approach

Stack Fit

  • Laravel Core:
    • Replaces or extends throttle middleware (Symfony’s RateLimiter is already used internally).
    • Integrates with Laravel’s Cache facade for storage (Redis, database, file).
  • Queue Workers:
    • Use reserve()->wait() in Laravel Horizon jobs to prevent overloading external APIs.
  • API Gateways:
    • Deploy at the Laravel level (vs. NGINX/Cloudflare) for fine-grained control.
  • Monetization:
    • Dynamic limits via config() or environment variables (e.g., APP_RATE_LIMIT_PRO=10000).

Stack Misalignment:

  • Edge Rate Limiting: Not suitable for CDN-level throttling (use Cloudflare/AWS WAF).
  • Legacy PHP (<8.1): Requires Symfony 6.4+ (Laravel 10+).

Migration Path

  1. Assessment Phase:
    • Audit existing rate-limiting logic (e.g., custom Redis scripts, sleep() delays).
    • Identify use cases: API endpoints, auth flows, queues, or CLI.
  2. Pilot Phase:
    • Replace throttle middleware for a single endpoint (e.g., /login).
    • Test with InMemoryStorage (single-instance) or CacheStorage (Redis).
  3. Full Rollout:
    • Migrate all throttle middleware to RateLimiter.
    • Implement compound limits for SaaS tiers (if needed).
    • Add Retry-After headers to API responses.
  4. Optimization:
    • Tune Redis/Memcached for low-latency storage.
    • Monitor retryAfter values and adjust token bucket policies.

Example Migration:

// Before (Laravel's throttle middleware)
Route::middleware(['throttle:5,1'])->group(function () {
    Route::post('/login', [LoginController::class, 'store']);
});

// After (Symfony RateLimiter)
Route::group(['middleware' => function ($request, $next) {
    $limiter = app(RateLimiterFactory::class)->create('login');
    if (!$limiter->consume(1)->isAccepted()) {
        return response()->json(['error' => 'Too many attempts'], 429)
            ->header('Retry-After', $limiter->getRetryAfter()->format('U'));
    }
    return $next($request);
}], function () {
    Route::post('/login', [LoginController::class, 'store']);
});

Compatibility

Component Compatibility Notes
Laravel 10+ ✅ Full support Uses Symfony 6.4+
Laravel 11+ ✅ Full support Uses Symfony 7.0+
Redis/Memcached ✅ Required for distributed storage CacheStorage wrapper
Database (Cache) ✅ Supported via Laravel’s Cache facade Slower than Redis
File Storage ✅ Supported (single-instance only) Not recommended for production
PHP 8.1+ ✅ Required Laravel 10+ enforces this
Symfony 6.4+/7.0+ ✅ Direct dependency No conflicts with Laravel
Laravel Queues reserve()->wait() works in Horizon jobs Prevents queue overload
API Clients Retry-After header compliance (RFC 6585) Reduces client-side retries

Sequencing

  1. Phase 1: Core API Rate Limiting
    • Replace throttle middleware for auth/payment endpoints.
    • Use CacheStorage with Redis for distributed Laravel.
  2. Phase 2: Queue Worker Protection
    • Apply reserve()->wait() to Horizon jobs calling external APIs.
  3. Phase 3: SaaS Tiering
    • Implement CompoundRateLimiterFactory for per-user + per-IP limits.
  4. **Phase
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport