---
title: "Laravel Quota: пакет для контролю лімітів споживання за календарні періоди"
url: https://laravelukraine.com/blog/laravel-quota-paket-dlia-kontroliu-limitiv-spozivannia-za-kalendarni-periodi
date: 2026-07-15
source: https://laravel-news.com/laravel-quota-usage-budgets-for-calendar-periods?utm_medium=feed&utm_source=feedpress.me&utm_campaign=Feed%3A+laravelnews
---

# Laravel Quota: пакет для контролю лімітів споживання за календарні періоди

Laravel Quota - це пакет для відстеження та контролю накопичувальних лімітів споживання ресурсів. Наприклад, ви можете встановити обмеження на 50 PDF-експортів на місяць, 1000 API-запитів на день, пул AI-кредитів на розрахунковий період тощо.

Пакет вирішує іншу проблему порівняно з вбудованим `RateLimiter` у Laravel: замість обмеження сплесків трафіку у ковзному вікні він підраховує споживання відносно бюджету, який скидається на межі календарного періоду. Крім того, він може зберігати цей лічильник у базі даних, а не лише у кеші.

## Основні можливості

Пакет надає наступний функціонал:

- **Періоди, вирівняні за календарем** - можна визначити `perMinute()`, `perHour()`, `perDay()`, `perWeek()`, `perMonth()`, `perYear()` або `period($start, $end)` для довільного вікна
- **Трейт `HasQuotas`**, який додає квоти до будь-якої Eloquent-моделі
- **Middleware для роутів** (`quota:exports,50,month`), який списує квоту лише при успішній відповіді
- **Бекенди на базі кешу або бази даних**, які можна перемикати для кожного виклику
- **Атомарне споживання** - блокування споживання навколо роботи, яку воно вимірює
- **Примусове дотримання бюджетів** - викидає HTTP 429, коли бюджет вичерпано

## Fluent API

Квота - це іменований лічильник, прив'язаний до власника, з лімітом і періодом. Після визначення квоти ви можете перевіряти її стан або витрачати:

```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);
```

Метод `consume()` повертає незмінний DTO `QuotaInfo`. Якщо ви хочете жорсткої помилки замість розгалуження логіки, метод `enforce()` викидає HTTP 429, коли бюджет вичерпано:

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

Для операцій, де подвійне списання справді має значення, метод `block()` обгортає callback у блокування, щоб два одночасні запити не могли обидва пройти перевірку доступної ємності:

```php
Quota::for('pdf_generation', $user)
    ->limit(50)
    ->perMonth()
    ->block(function () use ($pdfService) {
        $pdfService->generate();
    }, amount: 1, lockSeconds: 30);
```

## Квоти на Eloquent-моделях

Додайте трейт `HasQuotas`, і той самий builder стане доступний через модель:

```php
use ZaberDev\Quota\HasQuotas;

class User extends Authenticatable
{
    use HasQuotas;
}
```

```php
$user->quota('pdf_exports')->limit(25)->perMonth()->consume();
$user->quota('pdf_exports')->limit(25)->perMonth()->remaining();
```

При використанні бекенду бази даних записи є поліморфними, тому ви можете запитувати квоти моделі як будь-яке інше відношення:

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

## Middleware для роутів

Middleware `quota` приймає назву, ліміт, період і опціональний драйвер:

```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');
```

Важливо відзначити порядок виконання: доступна ємність перевіряється до запуску роуту, але квота списується лише тоді, коли повертається відповідь 2xx або 3xx. Запит, який завершується помилкою 500 або не проходить валідацію, не коштує користувачу нічого.

## Бекенди для зберігання

Типовий драйвер - `cache`, який використовує будь-яке сховище, налаштоване у вашому застосунку (працюють Redis і Memcached). Драйвер `database` натомість записує до таблиці `quotas`, що потрібно, коли лічильник пов'язаний з білінгом і не може зникнути при очищенні кешу. Ви можете обирати драйвер для кожного виклику:

```php
Quota::for('api_ping', $ip)->using('cache')->limit(5000)->perDay()->consume();
Quota::for('monthly_exports', $user)->using('database')->limit(50)->perMonth()->consume();
```

Метод `Quota::extend()` дозволяє зареєструвати власний бекенд з сервіс-провайдера, якщо вам потрібно інше місце для зберігання лічильників. Застарілі записи бази даних можна очищати за розкладом:

```php
use ZaberDev\Quota\Models\Quota;

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

## Встановлення

Пакет вимагає PHP 8.2 і підтримує Laravel 11, 12 та 13:

```bash
composer require zaber-dev/laravel-quota
php artisan vendor:publish --provider="ZaberDev\Quota\QuotaServiceProvider"
php artisan migrate
```

Файл конфігурації `config/quotas.php` встановлює типовий драйвер (`QUOTA_DRIVER`), сховище кешу та префікс ключів, назву таблиці бази даних і те, чи відправляються події.

Інструкції зі встановлення та повну документацію можна знайти на [GitHub](https://github.com/zaber-dev/laravel-quota).
