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 з гарантією результату.







