Download the PHP package monkeyscloud/monkeyslegion-rate-limit without Composer
On this page you can find all versions of the php package monkeyscloud/monkeyslegion-rate-limit. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download monkeyscloud/monkeyslegion-rate-limit
More information about monkeyscloud/monkeyslegion-rate-limit
Files in monkeyscloud/monkeyslegion-rate-limit
Package monkeyslegion-rate-limit
Short Description Production-grade rate limiting with token bucket and sliding window algorithms, Redis backend, per-route + per-user + per-IP composite buckets, and PSR-15 middleware for MonkeysLegion.
License MIT
Homepage https://monkeyslegion.com
Informations about the package monkeyslegion-rate-limit
MonkeysLegion Rate Limit
Production-grade rate limiting for MonkeysLegion Framework with token bucket and sliding window algorithms, Redis backend, and PSR-15 middleware.
Features
- Two algorithms: Token Bucket (burst-friendly) and Sliding Window (precise counting)
- Redis Lua scripts: Atomic operations — no race conditions at scale
- Composite key resolvers: Per-IP, per-user, per-route, or any combination (
ip+route,user+route) #[RateLimit]attribute: Repeatable, class + method targets, named limiter references- PSR-15 middleware: RFC-compliant rate limit headers
- Resilient storage: Fail-open/fail-closed modes with circuit breaker — no 500 errors when Redis is down
- MLC configuration: Full config file with env var overrides and named limiter definitions
- Telemetry integration: Optional metrics for monitoring (counters, gauges)
- GDPR compliance: Optional IP hashing, trusted proxy support
- PHP 8.4: Property hooks, backed enums, asymmetric visibility
Installation
For production use with Redis:
MLC Configuration
Copy the config file to your project's config/ directory:
Full Configuration Reference
Environment Variable Quick Reference
| Variable | Default | Description |
|---|---|---|
RATE_LIMIT_STORAGE |
redis |
Storage driver: redis or memory |
RATE_LIMIT_MAX_ATTEMPTS |
60 |
Default requests per window |
RATE_LIMIT_WINDOW_SECONDS |
60 |
Default window in seconds |
RATE_LIMIT_ALGORITHM |
token_bucket |
Default algorithm |
RATE_LIMIT_BY |
ip |
Default key strategy |
RATE_LIMIT_FAIL_OPEN |
true |
Allow traffic when Redis is down |
RATE_LIMIT_CIRCUIT_THRESHOLD |
3 |
Failures before circuit opens |
RATE_LIMIT_CIRCUIT_RECOVERY |
30 |
Seconds before retrying Redis |
REDIS_HOST |
127.0.0.1 |
Redis server host |
REDIS_PORT |
6379 |
Redis server port |
REDIS_RATE_LIMIT_DB |
1 |
Redis database for rate limit keys |
RATE_LIMIT_HASH_IPS |
false |
Hash IPs for GDPR compliance |
RATE_LIMIT_TELEMETRY |
true |
Enable telemetry counters |
Bootstrapping with the Provider
Automatic (Recommended)
The RateLimitProvider wires everything from MLC config in a single call:
The Provider creates:
$services['storage']— The storage backend (Redis → ResilientStorage wrapper)$services['manager']—RateLimiterManagerwith named limiters from config$services['middleware']—RateLimitMiddlewareready for the router
DI Container Registration
With Pre-existing Redis Connection
If your app already has a shared Redis connection (e.g., from the queue or cache package):
Manual Bootstrap (Without Provider)
Quick Start — Using Rate Limits
Attribute-Based (Recommended)
Programmatic Usage (Facade)
From Attribute (Standalone)
Use fromAttribute() to evaluate rate limits from a #[RateLimit] attribute without the middleware:
Redis Unavailability — Resilient Storage
Neither Laravel nor Symfony handle this. Both throw 500 errors when Redis goes down. MonkeysLegion is the first PHP framework to ship a built-in resilient rate limiter.
The Problem
| Framework | When Redis is Down |
|---|---|
| Laravel | ThrottleRequests throws ConnectionException → 500 error |
| Symfony | Rate Limiter throws exception → 500 error |
| MonkeysLegion | Configurable: fail-open, fail-closed, or fallback — your API keeps working |
Three Modes of Operation
| Mode | MLC Config | Behavior When Redis Is Down |
|---|---|---|
| Fail-Open | fail_open = true |
All requests allowed — no rate limiting |
| Fail-Open + Fallback | fail_open = true, fallback_driver = memory |
Per-process rate limiting (no cross-worker consistency) |
| Fail-Closed | fail_open = false |
All requests denied with 429 — maximum security |
Circuit Breaker Pattern
Development Without Redis
Or in the MLC file:
Note:
memorydriver is single-process. Rate limits are not shared across workers.
Router Integration
The rate limiter hooks into the router via the #[RateLimit] attribute system:
How It Works
ControllerScannerscans for#[RateLimit]attributes on controller classes and methods- Rate limit configs are stored in
meta['rate_limits']on eachRouteDefinition Router::dispatch()attaches_rate_limitsas a PSR-7 request attributeRateLimitMiddlewarereads_rate_limits, resolves keys, evaluates limits, returns 429 or adds headers
Backwards Compatibility
The existing #[Throttle] attribute continues to work — the scanner bridges it automatically:
Competitive Comparison
| Feature | MonkeysLegion | Laravel 13 | Symfony 7 |
|---|---|---|---|
| Token Bucket | ✅ | ❌ (fixed window) | ✅ |
| Sliding Window | ✅ | ❌ (fixed window) | ✅ |
| Redis Lua Atomic | ✅ | ✅ (Redis driver) | ❌ (uses locks) |
| Fail-Open Mode | ✅ | ❌ (500 error) | ❌ (500 error) |
| Circuit Breaker | ✅ | ❌ | ❌ |
| Fallback Storage | ✅ | ❌ | ❌ |
| MLC Config | ✅ | YAML/PHP | YAML |
| Composite Keys | ✅ (ip+route) |
❌ (manual) | ❌ |
| Stacked Limits | ✅ (repeatable attr) | ✅ | ✅ |
| PHP 8.4 Hooks | ✅ | ❌ | ❌ |
| PSR-15 Standard | ✅ | ❌ (custom) | ❌ (custom) |
| Named Limiters | ✅ | ✅ | ✅ |
| IP Hashing (GDPR) | ✅ | ❌ | ❌ |
Algorithms
Token Bucket
Best for APIs that allow burst traffic while maintaining a steady average rate.
- Capacity =
maxAttempts(burst size) - Refill rate =
maxAttempts / windowSecondstokens per second - Each request consumes
costtokens (default: 1) - Tokens refill continuously based on elapsed time
Sliding Window
Best for strict rate limiting with precise request counting.
- Tracks each request timestamp in a rolling window
- No burst allowance — exactly
maxAttemptsperwindowSeconds - Uses Redis sorted sets for O(log n) operations
Key Resolvers
| Resolver | Description |
|---|---|
ip |
Client IP (with trusted proxy support) |
user |
Authenticated user ID (falls back to IP) |
route |
Route pattern (e.g., /api/users/{id}) |
ip+route |
Per-IP per-route composite |
user+route |
Per-user per-route composite |
Response Headers
Follows RFC 6585 + draft-ietf-httpapi-ratelimit-headers.
On successful requests:
On rate-limited requests (429):
| Header | Description |
|---|---|
X-RateLimit-Limit |
Maximum requests allowed in the window |
X-RateLimit-Remaining |
Requests remaining in the current window |
X-RateLimit-Reset |
Unix timestamp when the window resets |
X-RateLimit-Policy |
Limit and window in {limit};w={seconds} format (draft spec) |
Retry-After |
Seconds until next request is allowed (only on 429) |
Telemetry Metrics
When telemetry is enabled, the middleware emits the following metrics via the callback:
| Metric | Type | Labels |
|---|---|---|
ml_rate_limit_allowed_total |
Counter | resolver, algorithm |
ml_rate_limit_denied_total |
Counter | resolver, algorithm |
ml_rate_limit_remaining |
Gauge | resolver, algorithm, remaining, limit |
Requirements
- PHP ^8.4
- ext-redis (recommended for production)
- PSR-7 HTTP Message ^2.0
- PSR-15 HTTP Server Middleware ^1.0
License
MIT License — see LICENSE for details.
All versions of monkeyslegion-rate-limit with dependencies
psr/http-message Version ^2.0
psr/http-server-handler Version ^1.0
psr/http-server-middleware Version ^1.0