Add randomised jitter to defers so many workers don’t all wake at the same instant:
Http::rateLimit(RateLimits::perMinute(30)->jitter(50)) // waits 0–50ms longer than needed
->get('https://api.example.com/orders');Jitter only applies when a request actually has to wait, and it only ever adds: a random 0 to jitter milliseconds lands on top of the real delay, so a request never goes out before its window has room. On a compound limit the widest jitter of any window applies. In a named profile, use the jitter key (milliseconds).
Deterministic tests
The randomness source is the injectable Randomizer contract (the default RandomRandomizer uses random_int). Swap it on the Limiter for deterministic tests:
use RoundlyConsulting\HttpClientRateLimits\Facades\RateLimits;
use RoundlyConsulting\HttpClientRateLimits\Jitter\Randomizer;
$limit = RateLimits::perSecond(1)->jitter(50);
// Always add the full +50ms so waits are deterministic in a test.
$limit->getLimiter()->setRandomizer(new class implements Randomizer {
public function between(int $min, int $max): int
{
return $max;
}
});Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.