Rate limiting обмежує, скільки запитів клієнт може зробити за проміжок часу. Захищає від перевантаження, перебору паролів і токенів, масового викачування даних і від одного «галасливого» клієнта, що забирає ресурси в інших.
Чим рахувати:
- за користувачем чи токеном - для автентифікованих запитів, найточніше;
- за IP - для анонімних (вхід, реєстрація, скидання пароля), з поправкою на NAT і проксі;
- за ендпоінтом: вхід - 5 спроб на хвилину, пошук - 60, звичайні запити - більше.
Алгоритми: фіксоване вікно (просто, але дозволяє «сплеск» на межі вікон), ковзне вікно, token bucket (дозволяє короткі сплески до місткості «відра» за стабільної середньої швидкості).
Відповідь при перевищенні - 429 Too Many Requests з підказками клієнту:
HTTP/1.1 429 Too Many Requests
Retry-After: 30
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
Retry-After каже, через скільки секунд повторити. X-RateLimit-* - поширена (хоч і нестандартна) практика; IETF працює над стандартними заголовками RateLimit і RateLimit-Policy.
У Laravel:
RateLimiter::for('api', fn (Request $request) =>
Limit::perMinute(60)->by($request->user()?->id ?: $request->ip())
);
Лічильники мають жити в спільному сховищі (Redis), інакше на кількох серверах кожен рахуватиме своє.
Клієнтам - обробляти 429 з експоненційною затримкою й випадковим розкидом (jitter), а не повторювати одразу. Шари захисту: ліміти на рівні CDN/WAF відсікають грубі атаки ще до застосунку, а застосунок обмежує за бізнес-логікою.