Laravel Quota: Usage Budgets for Calendar Periods | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com) [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles  ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

  [ home ](https://msaied.com)    [ articles ](https://msaied.com/articles)    Laravel Quota: Enforce Usage Budgets for Calendar Periods in Laravel        On this page       1. [  What Is Laravel Quota? ](#what-is-laravel-quota)
2. [  Key Features ](#key-features)
3. [  The Fluent API ](#the-fluent-api)
4. [  Quotas on Eloquent Models ](#quotas-on-eloquent-models)
5. [  Route Middleware ](#route-middleware)
6. [  Storage Backends ](#storage-backends)
7. [  Installation ](#installation)
8. [  Real Takeaways ](#real-takeaways)

  ![Laravel Quota: Enforce Usage Budgets for Calendar Periods in Laravel](https://cdn.msaied.com/424/b6dac94325ccc99dff6556fefb82969d.png)

 [  Laravel ](https://msaied.com/articles?category=laravel) [  Composer Pacakge ](https://msaied.com/articles?category=composer-pacakge)  #Laravel   #Packages   #Rate Limiting   #Usage Quota   #API  

 Laravel Quota: Enforce Usage Budgets for Calendar Periods in Laravel 
======================================================================

     14 Jul 2026      4 min read    ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said  

       Table of contents

1. [  01   What Is Laravel Quota?  ](#what-is-laravel-quota)
2. [  02   Key Features  ](#key-features)
3. [  03   The Fluent API  ](#the-fluent-api)
4. [  04   Quotas on Eloquent Models  ](#quotas-on-eloquent-models)
5. [  05   Route Middleware  ](#route-middleware)
6. [  06   Storage Backends  ](#storage-backends)
7. [  07   Installation  ](#installation)
8. [  08   Real Takeaways  ](#real-takeaways)

 What Is Laravel Quota?
----------------------

[Laravel Quota](https://github.com/zaber-dev/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 custom `period($start, $end)`
- A `HasQuotas` Eloquent 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:

```php
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()`:

```php
Quota::for('api_queries', $user)->limit(1000)->perDay()->enforce();

```

For work where a double-spend matters, `block()` wraps the callback in a lock:

```php
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:

```php
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:

```php
$activeQuotas = $user->quotas()
    ->where('period_end', '>', now())
    ->get();

```

Route Middleware
----------------

Apply quota enforcement directly to routes with the `quota` middleware:

```php
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:

```php
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:

```php
Schedule::command('model:prune', ['--model' => Quota::class])->daily();

```

Installation
------------

Requires PHP 8.2 and supports Laravel 11, 12, and 13:

```bash
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](https://laravel-news.com/laravel-quota-usage-budgets-for-calendar-periods)*

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fmsaied.com%2Farticles%2Flaravel-quota-enforce-usage-budgets-for-calendar-periods-in-laravel&text=Laravel+Quota%3A+Enforce+Usage+Budgets+for+Calendar+Periods+in+Laravel) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fmsaied.com%2Farticles%2Flaravel-quota-enforce-usage-budgets-for-calendar-periods-in-laravel) 

 Frequently Asked Questions 
----------------------------

  3 questions  

     Q01  How is Laravel Quota different from Laravel's built-in RateLimiter?        Laravel's RateLimiter throttles bursts of traffic using a sliding time window and is typically backed by cache only. Laravel Quota counts cumulative consumption against a named budget that resets on a fixed calendar boundary (e.g., the start of a month), and it can persist counts in the database so they survive cache flushes—making it suitable for billing-tied limits. 

      Q02  Does the route middleware charge the quota if the request fails?        No. The middleware checks capacity before the route runs but only consumes the quota when the response returns a 2xx or 3xx status code. Requests that result in a 4xx or 5xx response do not count against the user's budget. 

      Q03  When should I use the database backend instead of the cache backend?        Use the database backend when the quota count is tied to billing or any business-critical limit that must not be lost if the cache is flushed or expires. The cache backend is fine for soft limits where occasional resets are acceptable. 

  Continue reading

 More Articles 
---------------

 [ View all    ](https://msaied.com/articles) 

 [ ![New in Laravel 13: First-Party Image Manipulation](https://cdn.msaied.com/427/504aed7f9f1c4a1cd411c7c4a4b6bc7c.png) Laravel 13 Image Manipulation PHP 

### New in Laravel 13: First-Party Image Manipulation

Laravel 13 introduces a first-party image manipulation feature, removing the need for third-party packages for...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 15 Jul 2026     3 min read  

  Read    

 ](https://msaied.com/articles/new-in-laravel-13-first-party-image-manipulation) [ ![Filament v4 Testing with Pest: Resources, Actions, and Form Assertions](https://cdn.msaied.com/426/a81430a378b2849b6fbecb8235b9119f.png) filament pest testing 

### Filament v4 Testing with Pest: Resources, Actions, and Form Assertions

A practical guide to testing Filament v4 panels using Pest — covering resource page assertions, table action d...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 15 Jul 2026     3 min read  

  Read    

 ](https://msaied.com/articles/filament-v4-testing-with-pest-resources-actions-and-form-assertions) [ ![Laravel Legacy Bridge: Carry Authenticated Sessions from a Legacy PHP App into Laravel](https://cdn.msaied.com/429/5abced4ee695d6c03e3ae41bbf2fe4bb.png) Laravel PHP Session Management 

### Laravel Legacy Bridge: Carry Authenticated Sessions from a Legacy PHP App into Laravel

Laravel Legacy Bridge is a package that reads a legacy session cookie, decodes the payload from the legacy dat...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 15 Jul 2026     4 min read  

  Read    

 ](https://msaied.com/articles/laravel-legacy-bridge-carry-authenticated-sessions-from-a-legacy-php-app-into-laravel) 

   [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

Explore

- [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [Contact](https://msaied.com#contact-section)

Connect

- [   hello@msaied.com ](mailto:hello@msaied.com)
- [   +20 109 461 9204 ](tel:+201094619204)

© 2026 Mohamed Said. All rights reserved.

 [  ](https://github.com/EG-Mohamed) [  ](https://www.linkedin.com/in/msaiedm/) [  ](https://wa.me/201094619204) [  ](mailto:hello@msaied.com) [  ](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
