name: acc-create-rate-limiter
description: Generates Rate Limiter pattern for PHP 8.5. Creates request throttling with token bucket, sliding window, and fixed window algorithms. Includes unit tests.
Rate Limiter Generator
Creates Rate Limiter pattern infrastructure for request throttling and API protection.
When to Use
| Scenario | Example |
|---|
| API protection | Prevent abuse |
| Resource throttling | Database connection limits |
| Fair usage | Per-user request limits |
| Burst protection | Spike handling |
Component Characteristics
RateLimiterInterface
- Common interface for all algorithms
- Check and consume methods
- Remaining capacity queries
Algorithms
- Token Bucket: Smooth rate limiting with burst capacity
- Sliding Window: Time-based with sliding window log
- Fixed Window: Simple time-based counter
RateLimitResult
- Contains allowed/denied status
- Provides retry-after information
- Generates HTTP headers
Generation Process
Step 1: Generate Core Components
Path: src/Infrastructure/Resilience/RateLimiter/
RateLimiterInterface.php — Common interface
RateLimitResult.php — Result value object with headers
RateLimitExceededException.php — Exception with retry info
StorageInterface.php — Storage abstraction
Step 2: Choose and Generate Algorithm
Choose based on use case:
TokenBucketRateLimiter.php — For APIs with burst allowance
SlidingWindowRateLimiter.php — For strict per-time limits
FixedWindowRateLimiter.php — For simple rate limiting
Step 3: Generate Storage
RedisStorage.php — Production storage with TTL
Step 4: Generate Tests
{Algorithm}RateLimiterTest.php — Algorithm tests
RateLimitResultTest.php — Result value object tests
File Placement
| Component | Path |
|---|
| All Classes | src/Infrastructure/Resilience/RateLimiter/ |
| Unit Tests | tests/Unit/Infrastructure/Resilience/RateLimiter/ |
Naming Conventions
| Component | Pattern | Example |
|---|
| Interface | RateLimiterInterface | RateLimiterInterface |
| Token Bucket | TokenBucketRateLimiter | TokenBucketRateLimiter |
| Sliding Window | SlidingWindowRateLimiter | SlidingWindowRateLimiter |
| Fixed Window | FixedWindowRateLimiter | FixedWindowRateLimiter |
| Result | RateLimitResult | RateLimitResult |
| Exception | RateLimitExceededException | RateLimitExceededException |
| Test | {ClassName}Test | TokenBucketRateLimiterTest |
Quick Template Reference
RateLimiterInterface
interface RateLimiterInterface
{
public function attempt(string $key, int $tokens = 1): RateLimitResult;
public function getRemainingTokens(string $key): int;
public function getRetryAfter(string $key): ?int;
public function reset(string $key): void;
}
RateLimitResult
final readonly class RateLimitResult
{
public static function allowed(int $remaining, int $limit, \DateTimeImmutable $resetsAt): self;
public static function denied(int $limit, int $retryAfter, \DateTimeImmutable $resetsAt): self;
public function isAllowed(): bool;
public function isDenied(): bool;
public function toHeaders(): array; // X-RateLimit-* headers
}
Usage Example
// Create limiter
$limiter = new TokenBucketRateLimiter(
capacity: 100,
refillRate: 10.0, // 10 tokens per second
clock: $clock,
storage: new RedisStorage($redis)
);
// Check limit
$result = $limiter->attempt('user:123');
if ($result->isDenied()) {
throw new RateLimitExceededException(
key: 'user:123',
limit: $result->limit,
retryAfterSeconds: $result->retryAfterSeconds
);
}
// Add headers to response
foreach ($result->toHeaders() as $name => $value) {
$response = $response->withHeader($name, (string) $value);
}
Algorithm Comparison
| Algorithm | Burst Handling | Memory | Precision | Use Case |
|---|
| Token Bucket | Good (configurable) | Low | Medium | APIs with burst allowance |
| Sliding Window | Limited | High | High | Strict per-time limits |
| Fixed Window | Poor (boundary issues) | Low | Low | Simple rate limiting |
Anti-patterns to Avoid
| Anti-pattern | Problem | Solution |
|---|
| No Redis/Shared Storage | Per-instance limits | Use shared storage |
| Missing Headers | Client can't adapt | Return X-RateLimit-* headers |
| Single Algorithm | Doesn't fit all cases | Choose per use case |
| No Retry-After | Client spams | Always return retry timing |
| Synchronous Blocking | Thread blocking | Use non-blocking check |
References
For complete PHP templates and examples, see:
references/templates.md — All algorithm implementations
references/examples.md — Middleware example and tests