What Is Laravel Quota?
Laravel Quota (zaber-dev/laravel-quota) is a package for tracking and enforcing cumulative usage limits that reset on calendar boundaries. Think 50 PDF exports per month, 1,000 API queries per day, or a pool of AI credits per billing cycle.
It solves a different problem than Laravel's built-in RateLimiter. Instead of throttling bursts in a sliding window, it counts consumption against a named budget that resets at a predictable calendar boundary—and it can persist that count in the database rather than only in the cache.
Key Features
- Calendar-aligned periods:
perMinute(),perHour(),perDay(),perWeek(),perMonth(),perYear(), or a customperiod($start, $end) - A
HasQuotasEloquent trait to attach quotas directly to any model - Route middleware (
quota:exports,50,month) that only consumes the budget on a successful 2xx/3xx response - Switchable cache or database backends, configurable per call
- Atomic consumption via
block()to prevent double-spend under concurrency - Hard enforcement via
enforce(), which throws an HTTP 429 when the budget is exhausted
The Fluent API
A quota is a named counter scoped to an owner, with a limit and a period:
use ZaberDev\Quota\Facades\Quota;
$builder = Quota::for('api_queries', $user)
->limit(1000)
->perDay();
$builder->used();
$builder->remaining();
$builder->isExceeded();
$builder->hasCapacity(10);
$info = $builder->consume(5);
To fail hard instead of branching on the result, call enforce():
Quota::for('api_queries', $user)->limit(1000)->perDay()->enforce();
For work where a double-spend matters, block() wraps the callback in a lock:
Quota::for('pdf_generation', $user)
->limit(50)
->perMonth()
->block(function () use ($pdfService) {
$pdfService->generate();
}, amount: 1, lockSeconds: 30);
Quotas on Eloquent Models
Add the HasQuotas trait to any model and the same builder is available directly on the instance:
use ZaberDev\Quota\HasQuotas;
class User extends Authenticatable
{
use HasQuotas;
}
$user->quota('pdf_exports')->limit(25)->perMonth()->consume();
$user->quota('pdf_exports')->limit(25)->perMonth()->remaining();
With the database backend, quota records are polymorphic, so you can query them like any other relation:
$activeQuotas = $user->quotas()
->where('period_end', '>', now())
->get();
Route Middleware
Apply quota enforcement directly to routes with the quota middleware:
Route::post('/exports/generate', [ExportController::class, 'store'])
->middleware('quota:exports,50,month');
Route::post('/api/v1/query', [ApiController::class, 'query'])
->middleware('quota:api_query,1000,day,database');
Capacity is checked before the route runs, but the quota is only consumed when the response is 2xx or 3xx. A request that errors or fails validation costs the user nothing.
Storage Backends
The default driver is cache (Redis, Memcached, or any configured store). Switch to database when the count is tied to billing and must survive a cache flush:
Quota::for('api_ping', $ip)->using('cache')->limit(5000)->perDay()->consume();
Quota::for('monthly_exports', $user)->using('database')->limit(50)->perMonth()->consume();
Expired database rows can be pruned on a schedule:
Schedule::command('model:prune', ['--model' => Quota::class])->daily();
Installation
Requires PHP 8.2 and supports Laravel 11, 12, and 13:
composer require zaber-dev/laravel-quota
php artisan vendor:publish --provider="ZaberDev\Quota\QuotaServiceProvider"
php artisan migrate
Real Takeaways
- Laravel Quota is a calendar-reset budget system, not a sliding-window rate limiter.
- The
enforce()method returns an HTTP 429 automatically—no manual branching needed. - Use
block()for atomic consumption when concurrent requests could both pass the capacity check. - The database backend is the right choice for billing-critical counters that can't be lost on a cache flush.
- Route middleware only charges the budget on successful responses, protecting users from being penalized for server errors.
- Custom backends can be registered via
Quota::extend()in a service provider.
Source: Laravel Quota: Usage Budgets for Calendar Periods — Laravel News