Ограничения частоты
Runnev применяет два независимых лимита: частоту запросов и пропускную способность публикации. Оба сообщаются в каждом ответе, чтобы вы могли регулировать темп до того, как вас притормозят.
Лимиты
| Тип ключа | Частота запросов | Пропускная способность публикации | Область |
|---|---|---|---|
Боевой (rnv_live_) | 1000 запр. / мин | 60 МиБ / мин | На проект |
Тестовый (rnv_test_) | 120 запр. / мин | 6 МиБ / мин | На проект |
| Публичный демо-ключ | 60 запр. / мин | только подписка | На IP |
Оба лимита — это token bucket, которые пополняются непрерывно, поэтому короткий всплеск выше поминутной цифры допустим, пока среднее остаётся ниже неё.
Заголовки
Каждый ответ сообщает состояние корзины частоты запросов:
x-ratelimit-limit: 1000
x-ratelimit-remaining: 998
x-ratelimit-reset: 1785931200x-ratelimit-reset — это время Unix, к которому корзина, как ожидается, снова
заполнится. Когда вас притормаживают, 429 добавляет retry-after:
retry-after: 2
x-ratelimit-limit: 1000
x-ratelimit-remaining: 0
x-ratelimit-reset: 1785931200Как пополняется корзина
Боевой ключ получает 1000 токенов и пополняется со скоростью 1000 / 60 ≈ 16,7 токена в
секунду. Каждый запрос стоит один токен. Если вы потратите все 1000 в первую секунду, то дальше
будете получать примерно один запрос каждые 60 мс, пока не перестанете долбить. Разбор
примера: отправьте 1000 запросов мгновенно, и 1001-й будет отклонён с
retry-after: 1; подождите секунду — и снова доступно около 16 токенов.
Подписки и бюджет запросов
Подписка стоит один запрос в момент подключения и ничего — далее. Удержание её
открытой, сколь угодно долго, не опустошает корзину. Это намеренное проектное решение: продукт
рассчитан на соединения, живущие часами, поэтому списывать их посекундно с лимита частоты не имело
бы смысла. Считается только начальный GET.
Рекомендованный клиентский backoff
При 429 соблюдайте retry-after, если он есть. Иначе, а также при
5xx, отступайте экспоненциально с полным джиттером:
base, cap = 0.2, 20.0 # секунды
delay = min(cap, base * (2 ** attempt))
sleep = random.uniform(0, delay) # полный джиттер: любое значение из [0, delay]Полный джиттер (равномерный выбор из [0, delay]) разводит «стадо» куда лучше
фиксированного экспоненциального расписания, где все клиенты повторяют в один и тот же миг. Все
три SDK это реализуют.
Как оставаться под лимитом
Лимит частоты запросов считает запросы, а не события, поэтому группировка событий в пакеты — это способ передать больше данных, не упираясь в него. При боевом лимите 1000 запр./мин одно событие на запрос ограничивает вас примерно 16 событиями/с; сто событий на запрос поднимают это примерно до 1600 событий/с при том же самом лимите. Тогда связывающим ограничением становится лимит пропускной способности 60 МиБ/мин, который считает байты публикации. О компромиссе размера см. Группировка пакетов ради пропускной способности.