﻿# Heartbeat SSE и idle timeout: что именно поддерживает соединение

Как связать SSE comments, heartbeat и idle timeout: измерять паузы без данных отдельно от полезного ответа и проверять конкретный reverse proxy.

Автор: Команда Retrivium
Обновлено: 2026-11-01
Канонический URL: https://retrivium.ai/ru/journal/provider-sse-heartbeat-timeout-budget/
Language: ru

До первого полезного фрагмента модель может некоторое время не выдавать content. Между клиентом и движком при этом работают прокси с собственными правилами ожидания. SSE comment способен поддерживать соединение активным, но он не доказывает готовность ответа и не заменяет deadline запроса. Инженерная проверка должна наблюдать транспортную активность и прикладной прогресс отдельно, иначе долгий зависший запрос будет выглядеть здоровым.

## Определите смысл heartbeat

[OpenRouter описывает comments](https://openrouter.ai/docs/api_reference/streaming), которые периодически появляются в SSE для предотвращения таймаутов соединения. Это служебные данные формата, а не JSON-ответ модели. Parser не должен передавать строку comment напрямую в JSON.parse либо прибавлять её к пользовательскому тексту.

[Стандарт SSE](https://html.spec.whatwg.org/multipage/server-sent-events.html) задаёт правила comments независимо от конкретной платформы. Их обработка полезна для любого совместимого parser, но частота отправки и прикладная политика остаются свойствами выбранного сервиса. Не выводите обязательный интервал heartbeat для upstream из одного примера внешнего API.

## Разведите таймеры

Нужны отдельные измерения времени до headers, до первого content и между чтениями транспорта. Прикладной deadline может закончиться, хотя comments продолжают поступать. Аналогично длительный расчёт может быть допустим продукту, но соединение разорвётся на более коротком промежуточном idle timeout.

Запишите начало каждого таймера и событие, которое его сбрасывает. Если comment обновляет время transport activity, это не должно автоматически обновлять время last useful output. Различие особенно важно для наблюдаемости: интерфейс может показывать активную обработку, сохраняя честное сообщение о длительном ожидании результата.

## Проверьте конкретный прокси

[Руководство NGINX](https://nginx.org/en/docs/http/ngx_http_proxy_module.html) описывает proxy_read_timeout как настройку чтения ответа от upstream. Проверяйте реальную конфигурацию и область действия директивы. Число из конфигурации другого проекта не является доказанным пределом всей цепочки, в которой могут находиться дополнительные балансировщики и клиентские ограничения.

Измерение удобно начать с fake upstream, который отправляет headers, затем служебные comments, а content задерживает на контролируемый интервал. Такой стенд позволяет проверить таймеры без загрузки GPU. Все интервалы и общий срок теста задаются заранее, чтобы эксперимент гарантированно завершался.

## Сравните две трассы

Первая трасса молчит после headers, вторая посылает только heartbeat. Для каждой сохраните момент разрыва либо достижения общего deadline. Затем добавьте полезный content и нормальное завершение. Это покажет, какая часть поведения относится к idle policy, а какая к полному бюджету запроса.

Не делайте вывод по одному успешному прохождению. Укажите фактические интервалы получения, состояние buffering и место наблюдения. Если comments доходят пачкой, причина может находиться в промежуточном слое, а не в механизме генерации heartbeat на сервере.

## Не подменяйте прогресс доступностью

Живое соединение не гарантирует успешную генерацию. В метриках heartbeat не увеличивает число output tokens и завершённых ответов. Политика остановки долгого ожидания описывается отдельно; клиенту не следует бесконечно ждать только потому, что транспорт продолжает получать служебные bytes.

Инкрементальное чтение разобрано в [streaming-клиенте](/ru/journal/openrouter-streaming-client/), а эксплуатационная связь — в [сети и доступности](/ru/journal/network-and-uptime/). Итог проверки — карта таймеров конкретной цепочки без универсального SLA и без обещания, что comments устранят любую причину разрыва.
