Ретраи запроса ставки в RTB: что повторять после 204 и nbr
Повторять запрос ставки (делать ретрай) стоит только при технических сбоях: соединение не установилось, партнер вернул ошибку сервера, и при этом в бюджете tmax еще есть время. Отказ от ставки — HTTP 204 или ответ с кодом nbr — повторять бессмысленно, а при причинах вроде «бот» или «невалидный запрос» и вредно.
Как покупатель говорит «нет»: 204, пустой ответ и nbr
Спецификация OpenRTB 2.5 задает три HTTP-кода для обмена ставками:
| Код | Когда | Что значит |
|---|---|---|
200 OK |
Ответ с содержимым | Есть ставка (или ответ с nbr) |
204 No Content |
Валидный запрос, ответа нет | No-bid |
400 Bad Request |
Запрос испорчен или не разбирается | Ошибка на стороне отправителя |
В заметках к OpenRTB 2.6 IAB перечисляет формы no-bid, которые принимают многие биржи:
{}
{"id": "1234567890", "seatbid": []}
{"id": "1234567890", "seatbid": [], "nbr": 2}
Плюс пустой ответ с кодом 204 — самый экономный по трафику. Только последний вариант сообщает причину. Поле BidResponse.nbr необязательное: многие DSP его не заполняют, и 204 без причины — просто «не ставлю», без подробностей.
Откуда берутся коды nbr
Расшифровка каждого кода — в статье глоссария nbr. Для ретраев достаточно знать, какие коды вообще встречаются. Коды 0–10 заданы в OpenRTB 2.5 (раздел 5.24). Версия 2.6 своих перечислений не содержит и ссылается на список OpenRTB 3.0: там те же 0–10 и новые 11–17 про ads.txt, ads.cert, нехватку времени и schain. Значения от 500 — частные коды биржи, их смысл согласуют заранее. Причины проигрыша уже сделанной ставки — другой список, его разбирает статья «Почему проиграл аукцион».
Код → что значит → что делать
| Ответ | Повторять сейчас? | Что делать паблишеру или SSP |
|---|---|---|
204 без nbr |
Нет | Ничего: это нормальный no-bid. Следить за долей по партнеру |
| 0, 1 — неизвестная или техническая ошибка | Нет в этом аукционе | Технический сбой у покупателя. Если доля растет — сообщить партнеру, при массовых ошибках сработает circuit breaker |
| 2 — невалидный запрос | Нет | Исправить запрос: обязательные поля, типы, формат объектов. Повтор даст тот же ответ |
| 3, 4, 5 — робот, нечеловеческий трафик, IP датацентра или прокси | Нет, никогда | Трафик признан ботом или серверным. Разбираться с источником трафика, а не с покупателем |
| 6 — неподдерживаемое устройство | Нет | Устройство или окружение вне поддержки покупателя. Не слать ему такой трафик |
| 7 — площадка заблокирована | Нет | Площадка в блок-листе. Выяснить причину у покупателя |
| 8 — пользователь не сопоставлен | Нет | Нет идентификатора или синхронизации. Проверить передачу рекламного ID и согласий |
| 9, 10 — дневной лимит на пользователя или домен | Нет сегодня | Лимиты исчерпаны — запросы этому покупателю до конца суток малоценны |
| 11, 12 — проверка ads.txt | Нет | Обновить ads.txt или app-ads.txt |
| 13, 14 — подпись ads.cert | Нет | Проверить подпись ads.cert, если она используется |
| 15 — мало времени на аукцион | Нет | Увеличить tmax или сократить цепочку посредников, см. tmax и задержки |
| 16, 17 — неполная цепочка или заблокированный узел | Нет | Исправить schain: все узлы и complete |
| Сетевая ошибка до ответа | Можно, 1–2 раза | Если остаток времени позволяет — см. правила ниже |
5xx, 429 |
Не в этом аукционе | Следующие запросы — с задержкой и через circuit breaker |
Главная мысль таблицы: почти все коды nbr описывают свойство запроса, пользователя или площадки. За миллисекунды оно не меняется, поэтому повтор тратит ресурсы обеих сторон и ничего не приносит.
Где ретрай уместен, а где вредит
Различайте два вида повторов.
Внутри аукциона. SSP или биржа повторяет запрос к партнеру, пока показ еще ждет. Уместно, только если первая попытка упала до того, как партнер начал обработку: отказ в соединении, обрыв при установке TLS, мгновенный 503. Если же запрос ушел и партнер не ответил вовремя, повтор почти наверняка тоже не успеет — время уже потрачено.
Между аукционами. SDK или страница запрашивает рекламу заново, потому что предыдущая попытка не заполнила место. Здесь ретрай — по сути новый аукцион, и он должен идти с задержкой, а не в цикле. No-fill не ошибка: если подряд три пустых ответа, четвертый запрос через 100 мс почти наверняка тоже будет пустым.
Чем вредит неаккуратный ретрай:
- Дубли показов. Покупатель получил первый запрос, ответил, но ответ потерялся; повтор с новым
idвыглядит как второй показ — покупатель может дважды учесть частоту или дважды поставить на один показ. - Лавина. Партнер тормозит под нагрузкой, все ретраят — нагрузка удваивается, и он падает окончательно.
- Опоздание. Ретрай съедает время, которое нужно на ответ вверх по цепочке, и показ теряется целиком.
Правила безопасного ретрая
- Только идемпотентные сбои. Повторять можно ошибки, при которых партнер точно не обработал запрос или повтор не создаст нового события: отказ соединения,
502/503до чтения тела. No-bid иnbrне повторять. - Одна-две попытки, не больше. Каждая следующая попытка успешна реже предыдущей, а стоит столько же.
- Только в остатке tmax. Перед повтором проверить: хватит ли оставшегося времени на сеть туда, обработку партнера, сеть обратно и собственный ответ.
- Тот же
BidRequest.id. Повтор того же аукциона — тот же показ, поэтому идентификатор не меняется: так покупатель может склеить дубль. Если по договоренности с партнером повторы помечают (например, вext), это делают явно — стандартного поля для пометки нет. - Дедупликация на приеме. Обработчики ответов и уведомлений должны выдерживать повторную доставку: ключ — ID запроса и ID показа.
- Экспоненциальная задержка с джиттером — для повторов между аукционами и для фоновых операций вроде отправки уведомлений:
задержка(n) = случайное(0; min(потолок; база × 2^n))
n = 0, 1, 2… база = 200 мс потолок = 10 с
Случайная составляющая (джиттер) не дает тысячам клиентов повторять запрос синхронно, в одну и ту же миллисекунду. Для уведомлений о биллинге заметки к OpenRTB 2.6 советуют повторять вызов, если ответ не 200 и не 204, — например, раз в 10 секунд в течение минуты, — а принимающую сторону просят сделать обработчик идемпотентным, чтобы не считать показ дважды.
- Circuit breaker. Если доля ошибок партнера превысила порог, запросы к нему на время прекращаются полностью, затем пропускается пробная порция. Это защищает и партнера, и собственный аукцион: зачем ждать таймаута от того, кто сейчас не отвечает никому.
Пример: хватит ли времени на ретрай
Иллюстративный пример. SSP получила запрос с tmax = 300 мс и проводит аукцион среди партнеров.
| Статья бюджета | мс |
|---|---|
| Резерв на ответ вверх по цепочке и сериализацию | 40 |
| Время на опрос партнеров | 260 |
| Таймаут одного партнера | 120 |
Случай А. Партнер отказал в соединении через 15 мс. Осталось 245 мс — больше таймаута в 120 мс. Один повтор возможен, и даже при неудаче аукцион закончится вовремя: 15 + 120 = 135 мс < 260.
Случай Б. Партнер не ответил за 120 мс. Повтор с тем же таймаутом закончится на 240 мс — формально в бюджете. Но первая попытка уже показала, что партнер медленный; вероятность, что вторая успеет, низкая, а остальные ответы ждут. Здесь правильнее не повторять.
Случай В. Партнер вернул nbr: 5 (датацентр) за 30 мс. Времени много, но повтор бессмыслен: IP пользователя за это время не изменится.
Метрики, без которых ретраи вслепую
| Метрика | Как считать | Что показывает |
|---|---|---|
| Timeout rate | ответы позже таймаута / запросы | Медленный партнер или слишком короткий таймаут |
| Error rate | ответы не 200/204 и сетевые ошибки / запросы | Проблемы интеграции или инфраструктуры |
| No-bid rate | 204 и пустые ответы / запросы | Интерес покупателя к трафику |
Распределение nbr |
доли по кодам | Причины отказа: боты, лимиты, ads.txt |
| Доля ретраев | повторные запросы / все запросы | Не превратились ли ретраи в норму |
| Успешность ретраев | ответы со ставкой после повтора / повторы | Окупаются ли ретраи вообще |
| Время в открытом состоянии breaker | секунды в сутки по партнеру | Как часто партнер выпадает |
Если успешность ретраев близка к нулю, их нужно выключать: они только добавляют нагрузку. Связь этих метрик со ставками и показами удобно смотреть в воронке RTB.
Таймауты и отказы на бирже Ibiza
Биржа Ibiza опрашивает демандов общего аукциона параллельно и не повторяет запрос к партнеру после ошибки или таймаута. У каждого партнера свой таймаут, а общий срок аукциона — меньшее из настройки биржи и остатка tmax источника за вычетом резерва. В исходящем запросе биржа уменьшает tmax, чтобы деманд видел реальное время на ответ, а не исходное значение SSP. Каждый партнер работает через свой circuit breaker, а число одновременных соединений к нему ограничено, чтобы тормозящий деманд не утянул за собой весь аукцион. Ответ 204 от деманда — no-bid, а не ошибка; любой код кроме 200 и 204 — ошибка. Источнику биржа отвечает 204, если ставки нет или источник выключен, и 400 на неразбираемый запрос. DSP Ibiza отказывается от ставки ответом 204 без поля nbr, в том числе при перегрузке, и отвечает 400 на запросы без обязательных полей. Коды ответов для источников — в документации «Подключение SSP».
Частые вопросы
Что значит ответ 204 на запрос ставки?
Покупатель не ставит на этот показ. Это нормальный ответ, а не ошибка: повторять тот же запрос бессмысленно, причина не изменится за миллисекунды.
Почему повтор после таймаута почти не помогает?
Таймаут уже съел большую часть бюджета tmax, а партнер, не успевший один раз, под той же нагрузкой обычно не успевает и второй. Повтор оправдан, только если запрос упал сразу, до начала обработки.
Сколько раз можно повторять запрос ставки?
Внутри одного аукциона — не больше одного-двух раз и только при технической ошибке до получения ответа, если остаток tmax позволяет. Отказ с причиной, например бот или невалидный запрос, не повторяют вовсе.
Нужно ли повторять уведомление burl, если оно не дошло?
Да, в отличие от запроса ставки. Заметки IAB к OpenRTB 2.6 советуют повторять вызов при ответе не 200 и не 204, например раз в 10 секунд в течение минуты, а получателю — принимать повторы идемпотентно.