---
title: "The RateLimits facade — HTTP Client Rate Limits for Laravel | Roundly"
description: "The one entry point for building limits — per-window factories, profiles, compound limits, store and deferrer overrides, Retry-After, the fake."
url: https://roundly-consulting.com/open-source/docs/http-client-rate-limits-for-laravel/facade
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[HTTP Client Rate Limits for Laravel](https://roundly-consulting.com/open-source/docs/http-client-rate-limits-for-laravel.md)

# The RateLimits facade

The RateLimits facade is the package’s one entry point for building limits. It resolves the container-bound RateLimitManager singleton, so the configured store and deferrer — or a RateLimits::fake() — apply to every limit, including the ones Http::rateLimit() builds:

```php
use Illuminate\Support\Facades\Http;
use RoundlyConsulting\HttpClientRateLimits\Facades\RateLimits;

// Build a limit and attach it to a request.
Http::rateLimit(RateLimits::perSecond(5)->by('acct-1'))->get('https://api.example.com/orders');

// Profiles and compound windows come from the same place.
$github = RateLimits::profile('github');
$api    = RateLimits::compound([RateLimits::perSecond(5), RateLimits::perMinute(100)]);

// Inspect or clear a budget without sending anything.
$limit = RateLimits::perMinute(30)->by('acct-1');
$limit->remaining();
$limit->reset();
```

## The full surface

```php
use RoundlyConsulting\HttpClientRateLimits\Facades\RateLimits;

RateLimits::make(Limit $limit);                  // from a Limit value object
RateLimits::perSecond(int $maxAttempts = 1);     // N requests per second
RateLimits::perMinute(int $maxAttempts = 1);     // N requests per minute
RateLimits::perHour(int $maxAttempts = 1);       // N requests per hour
RateLimits::perDay(int $maxAttempts = 1);        // N requests per day
RateLimits::profile(string $name);               // a named profile from config
RateLimits::compound(array $limits);             // several windows at once
RateLimits::usingStore(Store $store);            // a copy of the manager on this store
RateLimits::usingDeferrer(Deferrer $deferrer);   // … or with this deferrer
RateLimits::releasingJob(object $job);           // … releasing a queued job instead of sleeping
RateLimits::retryAfter(Response|RequestException $response); // ?int seconds from Retry-After
RateLimits::store();                             // the shared default store
RateLimits::deferrer();                          // the default deferrer
```

| Method | Returns | Purpose |
| --- | --- | --- |
| `make(Limit $limit)` | RateLimit | Build from a Limit value object, on the manager’s store and deferrer. |
| `perSecond / perMinute / perHour / perDay(int $maxAttempts = 1)` | RateLimit | N requests per window. |
| `profile(string $name)` | RateLimit | A named profile from the limiters config, keyed by its by, else by its name; unknown names throw UnknownLimiterProfileException. |
| `compound(array $limits)` | RateLimit | Several windows at once; the first is primary, the strictest wins. |
| `usingStore(Store $store)` | RateLimitManager | A copy of the manager on this store; the singleton is untouched. |
| `usingDeferrer(Deferrer $deferrer)` | RateLimitManager | A copy of the manager with this deferrer. |
| `releasingJob(object $job)` | RateLimitManager | A copy that releases the queued job instead of sleeping (the ReleaseDeferrer). |
| `retryAfter(Response\|RequestException $response)` | ?int | Seconds from a Retry-After header (delta or HTTP-date); null when absent or unparseable. |
| `store()` | Store | The shared store new limits record hits in. |
| `deferrer()` | Deferrer | The deferrer new limits wait with. |
| `fake()` | RateLimitsFake | Swap in the recording test fake. |

## What a limit can do

Every factory returns a RateLimit — a Guzzle middleware you pass to Http::rateLimit() or Http::withMiddleware(), or wrap around any callable with handle(). It is fluent, and anything it doesn’t define itself is forwarded to the underlying Limit, then the Limiter:

| Group | Methods on the returned RateLimit |
| --- | --- |
| Configure (fluent) | `by(), alongside(), maxWait(), jitter(), adaptive(), setStore(), setDeferrer()` |
| Inspect | `remaining(), availableIn(), tooManyAttempts(), delayUntilNextRequestInMs(), getKey(), getMaxAttempts(), getTimespan(), isOverMaxAttempts(), isUnderMaxAttempts(), getStore(), getDeferrer(), getLimiter()` |
| Clear | `reset()` |
| Run | `handle(callable)` |

by() scopes every window the limit enforces; alongside() and compound() take copies of the limits you hand them, so re-keying the result never changes those.

## Per-call overrides

Override the store or deferrer for one call site without touching the global defaults:

```php
use RoundlyConsulting\HttpClientRateLimits\Deferrer\SleepDeferrer;
use RoundlyConsulting\HttpClientRateLimits\Facades\RateLimits;
use RoundlyConsulting\HttpClientRateLimits\Store\RedisStore;

// usingStore() / usingDeferrer() return a configured copy; the shared manager is untouched.
$limit = RateLimits::usingStore(new RedisStore('default'))
    ->usingDeferrer(new SleepDeferrer)
    ->perMinute(30);
```

Prefer an explicit dependency over a static call? See DI and actions — the injected manager has the same API.

## 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 crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## 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.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/http-client-rate-limits-for-laravel.md)
