NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

Open source

HTTP Client Rate Limits for Laravel

Install
composer require roundly-consulting/http-client-rate-limits-for-laravel
Requires: PHP ^8.4 · Laravel ^12.0|^13.0

Overview

Rate limit outgoing requests made with Laravel’s HTTP client. Declare a budget — per second, minute, hour or day — and a small Guzzle middleware paces your calls, waiting exactly as long as needed when the limit is reached, so you never blow past a third-party API’s quota. Every limit comes from one RateLimits facade, so the configured store — or a test fake — applies everywhere. Named profiles, compound windows, per-owner budgets, header-driven adaptive backoff and shared cache, Redis or database stores are built in. MIT-licensed and dependency-light: only official Laravel components plus two small Roundly packages.

What you get

One-line throttling

Http::rateLimit(30) on any request, or build limits with the RateLimits facade or an injected manager. It waits exactly as long as needed, then sends.

Profiles & compound windows

Define limits once in config and reference them by name. Enforce 5/sec and 100/min at once — the strictest window wins.

Shared stores

In-memory, any Laravel cache, Redis or the database — each checks and records a request in one atomic step, so workers sharing a budget never overshoot it.

Adaptive backoff

Reads Retry-After and X-RateLimit-* response headers and makes the next call wait exactly as long as the server asked.

Fail fast, jitter & queues

Cap the wait with a typed exception, spread wake-ups with jitter, or release queued jobs instead of blocking workers.

Events & testing fake

RequestDeferred, RequestAllowed and RateLimitReset events, plus a recording RateLimits::fake() with deferred, allowed and reset assertions.

Documentation

Installation

Install via Composer, optionally publish the config, and publish the migration only if you use the DatabaseStore.

Configuration

Every config key, its default and env variable — limiter profiles, default store and deferrer, cache, Redis, database and events.

The RateLimits facade

The one entry point for building limits — per-window factories, profiles, compound limits, store and deferrer overrides, Retry-After, the fake.

DI and actions

Inject RateLimitManager instead of calling the facade, or wire a RateLimit by hand — the package has no action classes.

Rate limiting requests

Throttle Laravel HTTP client calls with the Http::rateLimit() macro or the RateLimit Guzzle middleware, from per-second to per-day.

Per-owner budgets

Scope a limit to an owner — an account, tenant, API key or outbound IP — so independent callers never share a budget.

Named limiter profiles

Define reusable limits once in config and reference them by name — Http::rateLimit('github') — with every option available.

Compound limits

Enforce several windows on one request — 5 per second and 100 per minute — where the strictest window decides the wait.

Max wait & fail fast

Cap how long a call may wait; above the ceiling it throws RateLimitExceededException instead of blocking.

Jitter

Add random extra wait so a fleet of workers doesn’t wake up in lockstep — never less than the real wait; inject the randomness for tests.

Adaptive limiting

Honour the server’s own budget — read Retry-After and X-RateLimit-* headers and back off exactly as long as asked.

Retry-After & 429 retries

Combine the limiter with Laravel’s retry() and RateLimits::retryAfter() to honour 429 Too Many Requests responses.

Pre-flight inspection

Ask how many requests remain and how long until the next is allowed — without recording a hit — and reset a key’s budget.

Stores

Where request timestamps live — memory, any Laravel cache, Redis or the database — how each stays atomic, and how to write your own.

Deferrers & queued jobs

How the wait is performed — a millisecond sleep by default, or releasing a queued job back onto the queue.

Defaults & overrides

Set the default store and deferrer in config, override them per call site with RateLimits::usingStore() / usingDeferrer(), or per instance.

Events

RequestDeferred, RequestAllowed and RateLimitReset events to log, chart or alert on throttling — or switch them off for zero overhead.

Exceptions

Every typed exception the package throws, when it happens, and one base class to catch them all.

Timespan enum

The Timespan enum behind every window — second to day — with the full enums-for-laravel toolkit for labels, options and validation.

Testing

Swap in RateLimits::fake() to assert deferred, allowed and reset limits without real sleeps or Redis, or fake Laravel’s Sleep.

Requirements

PHP 8.4+ and Laravel 12 or 13; Redis only for the RedisStore, two database tables only for the DatabaseStore.

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

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