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

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

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

  [ home ](https://www.msaied.com)    [ articles ](https://www.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://www.msaied.com/articles?category=laravel) [  Composer Pacakge ](https://www.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%2Fwww.msaied.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%2Fwww.msaied.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://www.msaied.com/articles) 

 [ ![DDD Value Objects and DTOs in Laravel Without the Bloat](https://cdn.msaied.com/450/41688537085b86f102fd8c219a35319f.png) laravel ddd php 

### DDD Value Objects and DTOs in Laravel Without the Bloat

Learn how to implement domain-driven value objects and data transfer objects in Laravel using PHP 8.3 readonly...

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

 21 Jul 2026     1 min read  

  Read    

 ](https://www.msaied.com/articles/ddd-value-objects-and-dtos-in-laravel-without-the-bloat) [ ![Laravel + Python FastAPI: Image OCR Demo](https://cdn.msaied.com/447/5f3d87146fbf19957973cbc88c6c0155.png) Laravel Python FastAPI 

### Laravel + Python FastAPI: Image OCR Demo

Learn how to call a Python image OCR script from Laravel using FastAPI as the bridge. This premium tutorial wa...

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

 20 Jul 2026     3 min read  

  Read    

 ](https://www.msaied.com/articles/laravel-python-fastapi-image-ocr-demo) [ ![Scaffold Laravel Packages with the `laravel package` Command in Installer v5.31.0](https://cdn.msaied.com/449/522e744d3c7bae1f214c179a83ae5b88.png) Laravel Installer Package Development CLI 

### Scaffold Laravel Packages with the `laravel package` Command in Installer v5.31.0

Laravel Installer v5.31.0 introduces a `laravel package` command to scaffold packages from the CLI, automated...

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

 20 Jul 2026     3 min read  

  Read    

 ](https://www.msaied.com/articles/scaffold-laravel-packages-with-the-laravel-package-command-in-installer-v5310) 

   [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://www.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://www.msaied.com)
- [Projects](https://www.msaied.com/projects)
- [Articles](https://www.msaied.com/articles)
- [Certificates](https://www.msaied.com/certificates)
- [Contact](https://www.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)
