saloonphp/rate-limit-plugin
A Saloon plugin for respectful API clients: it tracks requests and handles rate-limit responses, retrying or delaying calls when limits are reached. Drop it into Saloon's middleware pipeline for simple, reliable rate-limit management.
Architecture fit
saloonphp/rate-limit-plugin is an add-on to Saloon, a framework-agnostic PHP HTTP client. It is not a Laravel package in the strict sense — it has no service provider, config file, or facade — but it is directly relevant to any Laravel service that makes outbound calls to third-party APIs with quotas (payments, messaging, carrier/booking APIs, SaaS rate-limited endpoints). It sits in the same layer as Saloon itself: behind an application-owned integration/service class, not in controllers. That is a healthy architecture fit, because rate limiting is a cross-cutting concern of the outbound-connector layer and this package keeps it there rather than leaking quota logic into domain code.
Integration feasibility Feasible and small: a Composer require plus plugin registration on each connector (or a trait on the connector base class). No infrastructure prerequisite beyond a cache store the package can reach. Expect hours, not weeks, for a first connector — the real effort is per-connector configuration of limits, which is business-knowledge work (what each vendor's actual quota is), not engineering work.
Technical risk This release is a patch that fixes a correctness defect: cached responses were being counted against the rate limit. Two consequences matter to a TPM.
Key questions
Stack fit
Composer package, PHP 8.x, no Laravel coupling. Works with any Laravel version whose PHP constraint matches; the only Laravel-specific decision is which cache store backs the limit counter. Redis (or another shared store) is the correct choice for any multi-instance deployment; array/file caches make limits per-process and are only acceptable in local dev.
Migration path
^2.5.3 so the fix is included from day one. No reason to accept earlier 2.5.x.composer update, no code change expected. Treat it as a behaviour change for review purposes regardless — re-run connector integration tests and compare 429 rates before/after.Compatibility Verify three constraints before merging: package's required Saloon core version, PHP version floor, and behaviour of the cache store under concurrency (atomic increment support — Redis yes, file cache no). Also confirm the caching plugin's version, since this fix lives at the intersection of the two.
Sequencing
Maintenance
Small, single-purpose package with an active 2.x line and external contributors — a good maintenance signal for a dependency of this size. Cost of ownership is low in code terms but non-zero in attention: this release proves patch versions can alter observable throughput, so composer update should not be fully automated for connectors carrying quota-sensitive traffic. A pinned constraint plus a human glance at the changelog is the right posture.
Support Community-supported via GitHub issues, not a vendor with an SLA. Acceptable for outbound-call hygiene; not acceptable as the only control if a vendor quota breach has contractual or financial consequences. For those vendors, layer a server-side/business-level guard (fallback, queue, circuit breaker) so enforcement does not depend solely on a community plugin.
Scaling The decisive variable is the cache backend. With shared Redis, limits are global and behave correctly across autoscaled workers. With a per-instance store, each worker gets its own budget and you will breach vendor quotas at exactly the moment traffic grows — a scaling failure that appears as an upstream 429 storm, not as an infrastructure alarm. Validate this before any autoscaling work.
Failure modes
Ramp-up Low. A developer already comfortable with Saloon picks this up in well under a day. The learning curve is not the API — it is knowing each vendor's true quota and window semantics, which is a product/partnership question. Budget time for that, and for writing one integration test per connector that combines caching and rate limiting.
How can I help you explore Laravel packages today?