perimeter/rate-limit-bundle
perimeter/rate-limit-bundle adds configurable rate limiting to Symfony applications, helping protect APIs, controllers, and routes from abuse. Define limits, choose storage, and throttle requests with minimal setup and flexible integration.
Architecture fit — poor, and the premise needs correcting. perimeter/rate-limit-bundle is a Symfony bundle, not a Laravel package. It integrates via Symfony's bundle registration, DI container, and kernel.request event listeners — mechanisms Laravel does not have. If the target application is Laravel, there is no drop-in path: the package's wiring layer is unusable and only a small amount of throttling logic could theoretically be lifted out.
Package profile (as provided):
| Signal | Value | Reading |
|---|---|---|
| Stars | 41 | Low visibility; no meaningful community |
| Dependents | 0 | No production validation to reference |
| Last release | 2015-02-27 | ~10 years stale; PHP 5.x / Symfony 2.x era |
| Score | 0.325 | Below any reasonable adoption threshold |
| License | MIT | Permissive, so forking is legally clean — the only positive signal |
Integration feasibility — low. Feasibility splits by stack:
RateLimiter (Illuminate\Cache\RateLimiting) and throttle middleware for years, with named limiters, per-key segmentation, and X-RateLimit-* / Retry-After headers. Reimplementing a 2015 Symfony bundle to reach parity with a feature already in the framework is negative-value work.symfony/rate-limiter has been first-party since 5.2 and covers the same ground with maintained code. The bundle would only make sense on a legacy Symfony 2.x application, which itself is a finding worth escalating.Technical risk — high. Unmaintained code from the PHP 5 era will not run cleanly on PHP 8.x (dynamic property deprecations, removed APIs, absent type declarations), has no CVE response process, and no maintainer answering issues. With zero dependents, there is no evidence anyone has run this in production recently, so unknown-unknowns are unquantified. The residual risk is not "will it break" but "who owns the fork forever."
Key questions for stakeholders:
429, Retry-After, X-RateLimit-Limit/Remaining/Reset)?Stack fit. Recommend rejecting this package and delivering the capability natively. For Laravel: RateLimiter::for() definitions in a service provider plus the throttle:<name> middleware on API route groups, backed by Redis. For Symfony: symfony/rate-limiter with a RateLimiterFactory and a request listener. Both give maintained code, PHP 8 support, and framework-idiomatic configuration.
Migration path. There is nothing to migrate — no existing consumers, no dependents, no data model to preserve. Treat this as greenfield. If someone has already prototyped with the bundle, the migration is a delete-and-replace, not a port; budget it as such rather than as an upgrade.
Compatibility. The package predates PSR-11 adoption, PHP 7 scalar types, and Symfony Flex. Even on a Symfony codebase it would require a compatibility fork spanning autoloading, container compilation, and event dispatcher signatures. Estimated effort to modernize exceeds writing the limiter from scratch — a comparison worth putting in the decision record so the "but it's MIT, we can fork it" argument is closed out with numbers.
Sequencing (recommended delivery):
429 with Retry-After and limit headers; document in the public API spec.If leadership insists on evaluating the package, timebox a two-day spike: fork, bump to PHP 8.2, run the test suite, measure what breaks. Expect the spike to end in a "no" — but the artifact converts an opinion into evidence.
Maintenance. Unmaintained upstream. Adopting it means the team inherits permanent ownership: PHP version bumps, framework upgrades, security patches, and dependency conflicts all become our backlog. On a 41-star, 0-dependent package, there is no realistic path to upstreaming fixes, so every change is a private fork divergence.
Support. No vendor, no active maintainer, no issue-tracker signal, no Stack Overflow corpus. Troubleshooting falls entirely to whoever reads the source. For a component sitting on the request path of every API call, that is a single-point-of-knowledge risk.
Scaling. Rate limiting scales only as well as its counter store. Requirements that must be explicit in the design: shared Redis for multi-instance correctness, TTLs on every counter key to bound memory, atomic increment-and-expire operations to avoid races, and avoidance of fixed-window counters on high-burst endpoints (prefer sliding window or token bucket). A 2015-era implementation may default to patterns that are correct for a single server and wrong for a fleet — verify rather than assume.
Failure modes to design for:
429.Ramp-up. The code itself is small; the cost is archaeological. Onboarding an engineer onto a dead Symfony 2 bundle teaches them nothing reusable and creates bus-factor-1 knowledge. By contrast, framework-native rate limiting is documented, familiar, and transferable — a materially better operational investment for the same product outcome.
Recommendation. Do not adopt. Record the decision as "capability required, package rejected on maintenance and ecosystem-fit grounds," and fund the native implementation. Re-evaluate only if a maintained, actively released alternative with real dependent count appears.
How can I help you explore Laravel packages today?