Квоты и retention
Тариф организации напрямую транслируется в два численных контракта: верхний предел ingestion (сколько логов и метрик в единицу времени принимает бэкенд) и срок хранения данных. Оба параметра вычисляются из тарифа и применяются отдельно для логов и метрик, без общего бюджета между ними. Когда клиент превышает лимит или данные выходят за окно хранения, система реагирует предсказуемо: ingestion возвращает HTTP 429 quota_exceeded, а ежедневная задача вычищает просроченные строки.
Семантика 429 quota_exceeded
При превышении лимита ingestion возвращает HTTP 429 с телом, содержащим error: quota_exceeded и reset_at — UTC timestamp момента, когда квота снова станет доступной. В том же ответе бэкенд устанавливает заголовок Retry-After со значением в секундах. При одновременном наличии обоих источников backoff Retry-After имеет приоритет как authoritative backoff: агент ждёт ровно столько секунд, сколько указано в заголовке, и только после этого сверяется с reset_at в теле. Такая комбинация закрывает два сценария — короткое мгновенное окно (заголовок) и точное абсолютное время разблокировки (поле).
Где применяются квоты
Квоты проверяются на приёмном слое — в ingestion-шлюзе, до записи данных в хранилище. Решение о приёме или отказе принимается сразу на входе: если батч не помещается в квоту, он отклоняется с 429, не тратя ресурсы хранилища. Дальше по пайплайну квоты уже никто не перепроверяет.
Per-org retention
Retention применяется per-org, а не через единый глобальный TTL на таблице: у каждой организации — своё окно хранения, вычисленное из её тарифа. Вычистку выполняет ежедневная фоновая задача. Конкретное значение retention для каждой организации вычисляется отдельно, поэтому удаление всегда кастомно на каждую организацию.
Поведение агента на 429
Получив 429 quota_exceeded, агент не роняет пайплайн: неотправленные батчи остаются в буфере — в памяти или в SQLite-буфере на диске, если включён persistent_buffer. Повторные попытки идут с экспоненциальным backoff и jitter, чтобы равномерно размазать нагрузку при восстановлении. Заголовок Retry-After уважается как authoritative — агент не шлёт запросы раньше указанного срока. Каждое событие quota_exceeded логируется как structured event и отражается в heartbeat, чтобы оператор видел состояние прямо в дашборде.