Разделение квот офлайн и онлайн без пустого лимита днем
Разберем, как настроить разделение квот офлайн и онлайн, чтобы ночные батчи не съедали бюджет, а дневные запросы не упирались в лимит к обеду.

Почему лимит заканчивается к обеду
Обычно причина простая: ночной batch начинает тратить токены раньше, чем команда открывает дневной бюджет для живого трафика. На бумаге лимит есть на весь день. По факту часть денег и токенов уже ушла в 3 или 4 часа утра, пока пользователи еще спят.
Проблема быстро становится заметной, если офлайн-обработка и онлайн-сценарии сидят на одном spend cap. Переиндексация, массовая разметка, обновление каталога, ночные summaries и продуктовый чат начинают есть один и тот же бюджет. Для провайдера или шлюза это просто общий поток запросов. Ему все равно, кто их отправил: batch, внутренний бот или клиентский интерфейс.
К 10-11 утра это проявляется очень приземленно. Поддержка получает ошибки по лимиту, внутренний бот отвечает медленнее, часть запросов уходит на fallback-модель с более слабым качеством. Иногда сервис не падает полностью, и это только мешает. Команда не сразу замечает проблему, а пользователи просто видят ответы хуже обычного или ждут на пару секунд дольше.
Средний отчет за сутки такое поведение маскирует. Он показывает, что вы "уложились" в дневной бюджет, и выглядит спокойно. Но почасовой срез рассказывает другую историю: ночью расход резко растет, утром доедает остаток, а днем система уже работает почти без запаса.
Это особенно заметно там, где весь LLM-трафик идет через один OpenAI-совместимый эндпоинт и общий биллинг. Команда меняет base_url, быстро подключает и продуктовый чат, и batch-задачи через один шлюз, и поначалу все выглядит удобно. Проблемы начинаются после первого тяжелого ночного прогона, если квоты не разделены.
Простой пример: ритейл-команда ночью прогоняет 120 тысяч карточек товаров, чтобы обновить описания и теги. К утру batch уже съел большую часть дневного лимита, хотя пик в клиентском чате начинается только в 9:30. Снаружи это выглядит как случайный сбой. На деле онлайн и офлайн просто спорят за один и тот же бюджет.
Если лимит пустеет к обеду, смотрите не на день целиком, а на первые часы после полуночи. Обычно источник проблемы виден сразу.
Что разделить в первую очередь
Если один общий лимит покрывает и ночной batch, и ответы пользователю, проблема почти неизбежна. Пока люди спят, фоновая обработка забирает деньги, RPM и TPM. Утром токены еще могут оставаться "по отчету", но живая нагрузка уже упирается либо в пустой запас по скорости, либо в сгоревший дневной бюджет.
Разделять лучше не абстрактные "типы задач", а зоны риска.
- Отдельный денежный лимит для онлайна и офлайна в пределах суток.
- Отдельные RPM и TPM для пользовательских запросов.
- Разные модели для batch-задач и ответов в интерфейсе.
- Отдельные очереди для разных команд, продуктов или сегментов.
- Резерв под ручные запуски, перевычисления и часы пика.
Деньги лучше делить жестко. Например, 70% суточного бюджета уходит на онлайн, 20% на ночной batch, еще 10% остается в резерве. Тогда каталог, переиндексация или массовая классификация не смогут съесть все до полудня.
С лимитами по скорости ошибаются еще чаще. Команда смотрит только на стоимость, хотя для онлайна важнее сохранить доступный RPM и TPM. Иначе чат поддержки начинает тормозить, даже если деньги еще не закончились. У живого трафика должен быть свой гарантированный коридор, который batch не трогает.
Модели тоже лучше не смешивать. Пользователь ждет стабильный ответ за секунды, а batch может терпеть дольше и работать на более дешевой модели. Это один из самых простых способов снизить бюджет LLM в продакшене без потери качества там, где его видит клиент.
Очереди стоит разделять по владельцу нагрузки. Если одна команда ночью гоняет переобогащение каталога, она не должна сжигать лимиты другой команды, которая держит чат или внутренний copilot. То же правило работает для разных продуктов и платных сегментов.
Резерв часто считают лишним, пока не случается сбой. Потом кто-то вручную перезапускает job, аналитики просят срочную выгрузку, а в онлайне начинается всплеск. Лучше сразу оставить хотя бы 10-15% дневного запаса вне обычного расписания.
Как посчитать дневную и ночную нагрузку
Начните с живых логов за последние 7-14 дней. Плановые цифры почти всегда расходятся с реальностью: продукт уже вырос, промпты стали длиннее, часть запросов ушла в ретраи и повторы. Нужны не ожидания команды, а фактическая картина.
Смотрите не только на число запросов. Для бюджета важнее почасовой расход в токенах и рублях. Рядом держите ошибки, таймауты и длину очереди. Именно они показывают, где система уже упирается в лимит, а где пока только делает вид, что все нормально.
Что смотреть по каждому часу
Для каждого часа за период соберите пять чисел:
- сколько запросов пришло в онлайн и в офлайн;
- сколько входных и выходных токенов они съели;
- сколько рублей вы потратили;
- сколько было ошибок, ретраев и таймаутов;
- какая очередь накопилась у batch-задач.
После этого не сводите все дни в одну среднюю цифру. Обычный вторник и плохой день с пиком ведут себя по-разному. Нужны хотя бы два профиля: нормальный день и день, когда трафик вырос, модель стала отвечать длиннее или ночной batch затянулся до утра.
Полезно собрать простую таблицу по часам. В ней сразу видно, в какой момент ночная обработка еще ест бюджет, а дневной онлайн уже стартовал. Часто проблема не в месячном лимите как таковом, а в пересечении двух волн нагрузки с 8 до 11 утра.
Потом добавьте запас. Не огромный, а понятный. После релиза промпты легко становятся длиннее на 10-20%, маркетинговая акция дает всплеск запросов, а массовый пересчет каталога или базы знаний внезапно удваивает ночной расход. Если считать без такого запаса, разделение квот офлайн и онлайн останется только на схеме.
Хороший ориентир простой: дневной лимит должен пережить плохой день без помощи ночного бюджета, а ночной лимит должен закрывать batch до начала рабочего пика. Если хотя бы одно условие не сходится, квоты нужно разводить жестче.
Как развести офлайн и онлайн по квотам
Если онлайн и batch сидят на одном лимите, batch почти всегда выигрывает. Он стартует раньше, обрабатывает длинные очереди и тратит бюджет в тот момент, когда пользователи еще спят. К обеду чат, поиск или API уже получают отказы, хотя общий дневной бюджет на старте выглядел нормальным.
Разделение квот офлайн и онлайн лучше строить не от месячной суммы, а от доступности сервиса по часам. Сначала закрепите за онлайном минимальный гарантированный бюджет до конца дня. Это запас, который batch не может трогать ни при каких условиях.
Как задать границы
Для онлайна обычно считают средний расход по часам, добавляют запас на пики и фиксируют отдельный порог. Если поддержка, поиск по базе знаний и пользовательский чат должны жить до 20:00, их лимит нужно резервировать заранее, а не оставлять по принципу "что останется после ночи".
Для batch лучше задать несколько простых правил: жесткий потолок на ночь, мягкий дневной потолок, лимит на одно окно запуска и стоп-условие, если онлайн подходит к своему порогу.
Такой режим работает лучше длинной очереди без пауз. Одна большая job не замечает, что днем начался пик запросов. Короткие окна по 15-30 минут дают планировщику шанс проверить остаток бюджета и вовремя остановиться.
Что делать с дорогими задачами
Тяжелый офлайн-поток не обязан идти на той же модели, что и онлайн. Если задача терпит немного более низкое качество, batch стоит переводить на более дешевые модели. Для тегирования, черновой классификации, очистки данных или массового переписывания карточек товаров это часто дает заметную экономию без вреда для результата.
Стоп-правило должно срабатывать автоматически. Если онлайн подошел, например, к 80% своего дневного порога раньше плана, офлайн-очередь нужно ставить на паузу сразу. Ручное решение почти всегда запаздывает.
Рабочая схема выглядит так: чат поддержки получает гарантированный бюджет до конца дня, а ночной пересчет каталога имеет жесткий потолок до 08:00 и мягкий дневной лимит после этого. Если днем трафик в чате растет, batch замедляется, переключается на более дешевую модель или останавливается. Даже если весь трафик идет через один эндпоинт, этого уже хватает, чтобы не ловить пустой лимит в рабочие часы.
Пример: каталог и чат
Ночью крупный ритейлер пересчитывает описания 200 тысяч товаров. Модель дописывает короткие тексты, чистит атрибуты, выравнивает стиль и иногда делает классификацию для поиска. Днем тот же бизнес отвечает покупателям в чате: "Есть ли размер M?", "Когда привезут?", "Чем отличается эта модель от прошлой?"
Проблема начинается, когда обе задачи сидят на одном лимите. Batch не чувствует боли от очереди в 20 минут, а чат чувствует сразу. Покупатель готов ждать секунду, максимум две. Если ночная обработка доедает общий бюджет утром, чат проседает ровно тогда, когда люди начинают заказывать.
Как это ломается на цифрах
Допустим, на одну карточку товара уходит в среднем 1800 токенов. Для 200 тысяч товаров это уже 360 миллионов токенов. Дневной чат может быть скромнее по объему, но приоритет у него выше: 25 тысяч диалогов в день по 1200 токенов дают еще 30 миллионов токенов.
На бумаге общий дневной лимит в 400 миллионов выглядит достаточным. По факту ночной batch легко съедает почти все еще до открытия смены. К 11 утра поддержка пишет, что ответы стали медленнее, а к обеду часть запросов уже упирается в пустой лимит.
В день распродажи это видно особенно резко. Каталог продолжает работать по плану, потому что batch уже запущен. Чат теряет приоритет в самый дорогой момент, когда покупатели готовы платить.
Что меняют отдельные квоты
Разделение квот офлайн и онлайн решает эту проблему без сложной перестройки кода. Для каталога вы задаете свой потолок по токенам, бюджету или RPS. Для чата - свой, с жестким резервом, который ночная задача не может занять.
Обычно схема простая: каталогу дают фиксированную ночную квоту и разрешают добирать остаток только если у онлайна есть запас. Чату, наоборот, резервируют дневной минимум, который нельзя трогать даже при длинной очереди batch-задач.
Для бизнеса разница очень простая. Карточки обновятся чуть позже, но покупатель не уйдет из корзины из-за молчащего чата.
Правила на случай аварии
Когда лимит уходит в ноль среди дня, команда часто начинает резать все подряд. Это плохой сценарий. Онлайн-трафик приносит мгновенный ущерб: чат молчит, операторы ждут, пользователи получают ошибки. Фоновые задачи почти всегда могут подождать час или доехать ночью.
Первое правило простое: держите несгораемый резерв только для онлайна. Не общий остаток бюджета, а отдельный карман, который batch не может тронуть ни при каком расписании. Такой резерв лучше считать не в процентах "на глаз", а в понятном объеме, например в часах обычной дневной нагрузки.
Даже если разделение квот офлайн и онлайн уже настроено, аварии все равно случаются из-за всплеска спроса или неудачного релиза. В такой момент batch не нужно выключать по первой ошибке, но и ждать полного отказа тоже не стоит.
Когда тормозить batch
Смотрите на два окна подряд, а не на один короткий всплеск. Если в двух соседних интервалах растут ошибки или задержка онлайна, фоновую обработку нужно сразу прижать до минимума или поставить на паузу. Иначе ночной поток продолжит есть бюджет именно тогда, когда он нужен живым пользователям.
Практический порог можно задать так:
- в первом окне batch теряет часть квоты и снижает скорость;
- во втором окне batch уходит на паузу;
- возвращается он только после нормализации задержки и ошибок.
Еще одно правило часто забывают. Запасную модель имеет смысл включать для чата, поиска и других пользовательских сценариев. Для фоновых задач это обычно лишняя трата. Если batch можно отложить, его лучше отложить, а не спасать дорогой резервной моделью.
Уведомления тоже должны приходить раньше. Сообщение после нуля бесполезно: инцидент уже случился. Лучше слать сигнал, когда осталось 10-15% дневного бюджета или квоты. Тогда у дежурного есть время снизить batch, переключить чат на более дешевую модель или временно закрыть тяжелые операции.
В аварии правило одно: сначала защищаете онлайн, а не пытаетесь делить последний остаток между всеми задачами.
Где команды чаще ошибаются
Первая ошибка скучная, но дорогая: команда смотрит на средний расход за сутки. Эта цифра почти всегда врет. Если ночью batch сжег большую часть токенов, дневной чат упрется в лимит уже к обеду, хотя среднее за 24 часа будет выглядеть терпимо.
LLM-нагрузку лучше считать по окнам, а не по суткам. Для онлайна важны часы с живыми пользователями, для офлайна - длинные серии запросов без пауз. Если ночью идет переиндексация каталога на 200 тысяч карточек, средняя линия на графике не покажет момент, когда batch занял весь запас RPM, TPM и бюджета.
Вторая частая ошибка: batch получает тот же rate limit, что и продакшен-чат. На бумаге это удобно, потому что все идет через один эндпоинт и один SDK. На практике ночной процесс начинает конкурировать с живыми запросами за те же лимиты. Даже если он стартует в 02:00, он легко доползает до утра и душит онлайн в первый час нагрузки.
Третья ошибка встречается почти в каждой зрелой команде. Тесты, переиндексация, миграции, eval-прогоны и реальные пользовательские запросы живут в одном пуле. Потом кто-то запускает длинный тест после релиза, и метрики показывают "рост спроса", хотя это всего лишь внутренний прогон. Без отдельного учета вы не понимаете, кто именно съел бюджет.
Еще один частый промах - один общий fallback для всего трафика. Сценарий простой: основная модель отвечает медленнее, система переключает и чат, и batch, и тесты на запасную модель. В пиковый час расход нередко вырастает почти вдвое, потому что часть запросов успевает сходить два раза. Для офлайна такой fallback часто вообще не нужен. Ему проще подождать в очереди, чем сжечь дневной лимит.
И еще одна мелочь, которая потом дорого стоит: команда меняет модель или промпт и не пересчитывает бюджет. Новый шаблон добавил 600 токенов в контекст, reasoning-модель стала отвечать длиннее, расписание batch осталось прежним, и старые лимиты больше не сходятся.
Короткая проверка перед запуском
Ночной запуск лучше проверять по короткому списку, а не по ощущениям. Иначе batch спокойно съест токены до утра, и онлайн-сервис встретит рабочий день с пустым запасом.
Сначала отделите онлайн от офлайна на уровне лимитов. У чата, поиска, рекомендаций и других живых сценариев должны быть свой бюджет, свой RPM и свой TPM. Не общий пул на все задачи, а отдельный контур, который ночная очередь не трогает.
Хорошее правило простое: дневной резерв нельзя отдавать batch-задаче ни при каких условиях. Если на рабочий день вам нужно 40% суточного лимита, этот объем должен быть забронирован заранее. Ночная обработка работает только в своем коридоре и останавливается, когда доходит до порога.
Batch нужно останавливать автоматически по понятному условию. Обычно хватает четырех сигналов: достигнут денежный порог на ночь, выбрана доля TPM для офлайна, онлайн начал расти быстрее прогноза, ошибка провайдера подняла стоимость или время ответа.
Отдельно проверьте мониторинг. Один график с общим расходом мало что дает. Нужен разрез по часам и по типу трафика: онлайн, batch, тесты, внутренние прогоны. Тогда утром видно не просто то, что бюджет просел, а кто именно его сжег и в какой час это произошло.
Для быстрой проверки перед запуском хватит пяти вопросов:
- у онлайна есть отдельный лимит по деньгам и токенам;
- batch знает свой порог остановки;
- мониторинг разделяет трафик по типам;
- дневной резерв исключен из ночной очереди;
- команда заранее знает, кто поднимает лимит и кто жмет стоп.
Последний пункт часто недооценивают. В 9:30 спор о том, кто имеет право остановить job, обходится дороже самой job. Назначьте двух ответственных заранее: один может временно поднять лимит, второй может без согласований остановить batch.
Что сделать дальше
Начните не с роста лимита, а с учета. Если online-запросы и batch-задачи живут в одном бюджете, вы почти всегда платите за это днем: чат, поиск или API для клиентов упираются в пустой пул, который ночью уже съел batch.
На практике разделение квот офлайн и онлайн лучше оформлять как отдельные контуры с разными правилами. Это не сложная архитектура. Во многих командах хватает двух бюджетов, двух наборов лимитов и явного маршрута для каждого типа нагрузки.
Для начала достаточно четырех шагов: выделить отдельные квоты для online и batch, проверить где batch можно перевести на более дешевую модель, зафиксировать окна запуска и пороги остановки, а также заранее назначить ответственных за ручное вмешательство.
Потом посмотрите на экономику. Ночной batch редко требует той же модели, что и дневной пользовательский трафик. Если задача каталога, классификации или разметки терпит более долгий ответ, часто выгоднее увести ее на дешевую модель, чем держать высокий дневной запас на всякий случай.
Нужен и короткий регламент. В одном документе стоит зафиксировать три вещи: когда стартует batch, при каком остатке бюджета он останавливается и кто принимает решение в спорной ситуации. Иначе в аварии все видят проблему, но никто не режет нагрузку первым.
Если у вас весь трафик уже идет через один шлюз, полезно завести отдельные маршруты и идентификаторы учета для онлайна и офлайна. В случае с RU LLM это особенно удобно: можно оставить прежние SDK, код и промпты, просто сменить base_url на api.rullm.com, а маршрутизацию, биллинг и аудит вести через один вход внутри РФ. Для сценариев, где ночной batch и дневной лимит нужно считать отдельно, это заметно упрощает контроль.
Если сделать только одно изменение на этой неделе, разделите бюджеты. Это самый быстрый способ не остаться без дневного лимита к обеду.