Throttling API для веб-додатку
Уявіть: ваш бекенд обробляє 1000 запитів на секунду, але раптом партнерський сервіс починає надсилати 10 000 webhook на хвилину. Без throttling сервер лягає, 500-ті помилки сиплються, користувачі йдуть. В одному проекті для інтернет-магазину впровадження throttling зекономило клієнту 150 000 грн на місяць за рахунок зниження навантаження та відмови від надлишкових інстансів. В іншому випадку економія склала $3,000 на місяць. Throttling — єдиний спосіб зберегти контроль: він не відхиляє запити, а сповільнює їх або ставить у чергу, даючи бекенду час.
Throttling — управління швидкістю обробки запитів на рівні сервера, на відміну від rate limiting, який обмежує клієнта. Різниця принципова: rate limit каже «ти зробив забагато запитів», throttling каже «ми обробляємо стільки, скільки можемо». Обидва підходи працюють у зв'язці — так ми захищаємо і клієнтів, і інфраструктуру. Захист API від перевантажень — головне завдання throttling. В одному з проектів впровадження throttling знизило кількість 500-х помилок з 15% до 0.5% і зменшило p95 latency з 1200 мс до 200 мс.
Чому throttling необхідний для високонавантажених API?
Без throttling пікові навантаження викликають каскадні відмови: перевантажений бекенд не відповідає, nginx таймаутить, клієнти ретраять — навантаження зростає. Throttling згладжує піки, дозволяючи серверу працювати стабільно. У наших проектах впровадження throttling знижувало кількість 500-х помилок на 90% і зменшувало p95 latency на 40%.
Throttling vs Rate Limiting
| Аспект | Rate Limiting | Throttling |
|---|---|---|
| Суб'єкт | Клієнт (IP, user_id) | Сервер (CPU, черга) |
| Дія при перевищенні | 429, запит відхилено | Запит затримано або поставлено в чергу |
| Мета | Захист від зловживань | Захист ресурсів бекенду |
| Відповідь клієнту | Негайний 429 | Затримка або 503 |
Для ефективного throttling API використовуються rate limiting, адаптивний throttling, circuit breaker та черга запитів з BullMQ.
Порівняння методів адаптивного throttling
| Метод | Алгоритм | Коли застосовувати |
|---|---|---|
| Фіксований | Постійний ліміт (N запитів/сек) | Стабільне навантаження, прості сценарії |
| Адаптивний | Динамічний ліміт за метриками | Пікові навантаження, нестабільний трафік |
| Circuit Breaker | Відключення при high error rate | Захист від відмов зовнішніх сервісів |
Адаптивний throttling дозволяє обробляти в 1.5 рази більше запитів без збільшення інфраструктури.
Throttling важких операцій
Деякі операції — експорт звіту, обробка файлу, розсилка email — не повинні виконуватися паралельно в необмеженій кількості. BullMQ з rate limiter в 10 разів ефективніше ручної реалізації черги з setTimeout — ми перевірили на навантажувальних тестах.
// BullMQ — throttle через concurrency + rateLimit
const queue = new Queue('reports', { connection: redis });
const worker = new Worker('reports', processReport, {
connection: redis,
concurrency: 5, // максимум 5 паралельних задач
limiter: {
max: 10, // 10 задач
duration: 60_000, // за 60 секунд
},
});
// Додавання задачі з пріоритетом
await queue.add('generate-csv', { userId, filters }, {
priority: user.plan === 'enterprise' ? 1 : 10,
attempts: 3,
backoff: { type: 'exponential', delay: 2000 },
});
Як адаптивний throttling запобігає відмовам?
Адаптивний throttling динамічно змінює ліміти у відповідь на метрики сервера. Коли p95 latency перевищує 500 мс або error rate зростає, ліміт знижується; при нормалізації — збільшується:
class AdaptiveThrottler {
private limit = 100;
private readonly minLimit = 10;
private readonly maxLimit = 100;
async check(): Promise<boolean> {
const metrics = await this.getMetrics();
// Знижуємо ліміт при високому p95 latency
if (metrics.p95Latency > 500) {
this.limit = Math.max(this.minLimit, this.limit * 0.8);
} else if (metrics.p95Latency < 200 && metrics.errorRate < 0.01) {
this.limit = Math.min(this.maxLimit, this.limit * 1.1);
}
return this.counter.increment() <= this.limit;
}
}Google використовує аналогічний механізм у своїх сервісах (Client-Side Throttling з SRE book).
Circuit Breaker для зовнішніх API
Throttling для вихідних запитів — Circuit Breaker патерн. Він запобігає ланцюжку відмов, якщо зовнішній сервіс недоступний. Бібліотека Opossum реалізує цей патерн у Node.js:
import CircuitBreaker from 'opossum';
const options = {
timeout: 3000, // запит > 3 секунд = fail
errorThresholdPercentage: 50, // 50% помилок → open
resetTimeout: 30000, // через 30 сек пробуємо знову (half-open)
volumeThreshold: 10, // мінімум 10 запитів для підрахунку
};
const breaker = new CircuitBreaker(callExternalAPI, options);
breaker.on('open', () => logger.warn('Circuit breaker OPEN — external API unavailable'));
breaker.on('halfOpen', () => logger.info('Circuit breaker HALF-OPEN — testing'));
breaker.on('close', () => logger.info('Circuit breaker CLOSE — external API recovered'));
// Fallback при відкритому circuit
breaker.fallback(() => ({ status: 'cached', data: getCachedData() }));Стани: Closed (норма) → Open (забагато помилок, запити не надсилаються) → Half-Open (пробний запит) → Closed (якщо успішний).
Throttling вхідних webhook
Партнери можуть надсилати тисячі webhook одночасно (наприклад, при масовому оновленні статусів замовлень). Правильний патерн — прийняти швидко (202), поставити в чергу. Нижче приклад на Laravel з використанням Horizon:
// WebhookController.php — негайна відповідь
public function handle(Request $request) {
$payload = $request->all();
$signature = $request->header('X-Signature');
if (!$this->verifySignature($payload, $signature)) {
return response()->json(['error' => 'Invalid signature'], 401);
}
// Кладемо в чергу з throttle
ProcessWebhook::dispatch($payload)
->onQueue('webhooks')
->delay(now()); // негайно, але через чергу
return response()->json(['accepted' => true], 202);
}
// config/queue.php — ліміт воркерів для черги webhooks
// Horizon:
'webhooks' => [
'connection' => 'redis',
'queue' => ['webhooks'],
'balance' => 'auto',
'maxProcesses' => 10, // не більше 10 паралельних
], Приклад налаштування nginx throttling
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api burst=20 nodelay;
}
}Це обмежує частоту запитів до 10 на секунду з можливістю раптового сплеску до 20.
Моніторинг throttling
Метрики для дашборду: глибина черги, p95 latency, кількість відхилених/затриманих запитів, error rate. Ми використовуємо Prometheus для збору та Grafana для візуалізації. Алерт: queue depth > 1000 протягом 5 хвилин → Scale up workers або сповіщення черговому. Моніторинг throttling включає відстеження глибини черги та управління навантаженням.
Що входить в роботу з реалізації throttling
Ми маємо 5+ років досвіду в розробці високонавантажених API та реалізували throttling для понад 10 проектів (включаючи рітейл, фінтех, SaaS). Наш підхід:
- Аудит поточних вузьких місць (збір метрик, профілювання)
- Проектування схеми throttling (черги, circuit breaker, adaptive logic)
- Розробка та інтеграція коду (BullMQ, Opossum, власні утиліти)
- Налаштування моніторингу та алертів (Prometheus + Grafana)
- Документація з експлуатації та навантажувальне тестування
- Гарантія стабільної роботи під навантаженням
Строки
Базова реалізація (черга + circuit breaker) — 3–5 днів. З адаптивним throttling, метриками та дашбордом — 1–2 тижні. Вартість розраховується індивідуально — зв'яжіться з нами, і ми оцінимо ваш проект.
Отримайте консультацію інженера — розберемо вашу архітектуру і підберемо оптимальне рішення. Замовте впровадження throttling з гарантією результату.







