ttools
APIоптимизациярасчеты

Как рассчитать лимит запросов API: формула и примеры

Разбираемся с rate limiting в API: считаем requests per second, определяем оптимальные интервалы между запросами.

Когда подключаешь API к своему проекту, первое, с чем сталкиваешься — rate limiting. Провайдер устанавливает лимит: 100 запросов в минуту, 10 000 в день или 50 в секунду. Важно понимать, как эти цифры пересчитывать и какой интервал между запросами выбрать, чтобы не словить бан и не потерять в скорости.

Базовая формула для расчёта интервала

Самая простая задача — понять, как часто можно слать запросы, если провайдер даёт лимит на период времени.

Формула:

Интервал (мс) = (Период в секундах × 1000) / Лимит запросов

Пример: API разрешает 60 запросов в минуту.

const limit = 60;
const periodSeconds = 60;
const intervalMs = (periodSeconds * 1000) / limit;
// intervalMs = 1000 мс (1 секунда между запросами)

Если лимит 100 запросов за 10 секунд:

const limit = 100;
const periodSeconds = 10;
const intervalMs = (periodSeconds * 1000) / limit;
// intervalMs = 100 мс (0.1 секунды между запросами)

Эта формула даёт теоретический минимум. В реальности добавляй запас 10-20%, чтобы учесть задержки сети и обработки.

Requests per second: как считать RPS

Многие API указывают лимит в формате «X запросов в секунду» (RPS). Чтобы пересчитать любой лимит в RPS, делим количество запросов на период в секундах.

Формула:

RPS = Лимит запросов / Период в секундах

Примеры:

  • 1000 запросов в час = 1000 / 3600 = 0.28 RPS
  • 100 запросов в минуту = 100 / 60 = 1.67 RPS
  • 10 000 запросов в день = 10000 / 86400 = 0.12 RPS

RPS удобен для быстрого сравнения разных API. Видишь сразу, что «100 в минуту» щедрее, чем «1000 в час», хотя на первый взгляд цифры похожи.

Реальные примеры лимитов популярных API

YouTube Data API

  • 10 000 квот в день
  • 1 запрос = от 1 до 50 квот (зависит от операции)
  • Реальный лимит: примерно 200-10 000 запросов в день

Расчёт для простого поиска (1 квота = 100 единиц):

const dailyQuota = 10000;
const costPerRequest = 100;
const maxRequests = dailyQuota / costPerRequest; // 100 запросов в день
const rps = maxRequests / 86400; // 0.0012 RPS
const intervalMs = 86400000 / maxRequests; // 864000 мс (14.4 минуты)

Twitter API v2 (Free tier)

  • 50 запросов на 15-минутное окно
  • RPS = 50 / 900 = 0.056 RPS
  • Интервал: 18 секунд между запросами

Stripe API

  • 100 запросов в секунду для большинства endpoint
  • RPS = 100
  • Интервал: 10 мс между запросами

Stripe один из самых щедрых. Twitter — один из самых жадных.

Burst и скользящее окно: подводные камни

Некоторые API используют токен bucket или скользящее окно (sliding window). Простой расчёт интервала тут не работает.

Токен bucket: можешь сделать burst (серию быстрых запросов), пока есть токены. Потом ждёшь, пока они восстановятся.

Пример: GitHub API позволяет 5000 запросов в час, но можно слать 100 подряд, если не исчерпал лимит ранее. Интервал между burst-ами:

const burstSize = 100;
const hourlyLimit = 5000;
const refillTimeMs = 3600000 / (hourlyLimit / burstSize);
// refillTimeMs = 72000 мс (1.2 минуты на восстановление 100 токенов)

Скользящее окно: лимит считается не от начала минуты/часа, а от момента первого запроса. Если отправил 50 запросов в 12:00:00, следующие 50 можешь слать только после 12:01:00.

В таких случаях безопаснее держать равномерный темп, а не бить в начале периода.

Как учесть retry и ошибки

Если запрос упал по таймауту или 5xx, ты его повторяешь. Повторные попытки тоже считаются в лимит.

Стратегия:

  1. Резервируй 20% лимита под retry
  2. Используй exponential backoff (каждая попытка в 2 раза дольше)
const baseLimit = 100;
const retryReserve = 0.2;
const effectiveLimit = baseLimit * (1 - retryReserve); // 80 запросов
const intervalMs = 60000 / effectiveLimit; // 750 мс между запросами

async function fetchWithRetry(url, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url);
      if (response.ok) return response;
      if (response.status === 429) {
        const retryAfter = response.headers.get('Retry-After') || Math.pow(2, i);
        await sleep(retryAfter * 1000);
      }
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await sleep(Math.pow(2, i) * 1000);
    }
  }
}

Header Retry-After подсказывает, сколько секунд ждать. Если его нет — используй backoff: 1 сек, 2 сек, 4 сек.

Инструменты для работы с API и расчётами

Когда настраиваешь интеграцию с API, часто нужно быстро обработать данные: закодировать URL-параметры, преобразовать JSON, сгенерировать хеш для подписи запроса. Вместо того чтобы писать скрипты, можно использовать готовые онлайн-инструменты.

Для кодирования параметров запросов пригодится URL Encoder/Decoder — он преобразует спецсимволы в формат, который API корректно обработает. Если работаешь с JSON-ответами, JSON Formatter отформатирует и валидирует структуру данных, чтобы быстро найти ошибку. А для подписи запросов через HMAC подойдёт HMAC Generator — просто вставляешь секретный ключ и payload, получаешь готовую подпись.

Эти инструменты экономят время на отладке и помогают не держать в голове синтаксис каждой функции кодирования.

Инструменты по теме