Когда код подтверждения идёт минуту, пользователи не ждут вежливо: они обновляют страницу, запрашивают код заново и бросают регистрацию. Задержка доставки — видимая пользователю характеристика продукта, но большинство команд никогда не измеряет её системно. Временный ящик даёт дешёвую, повторяемую точку наблюдения: запустить отправку, следить за ящиком, зафиксировать время увиденного. Сложная часть — получить цифры, которые выдерживают проверку. Это руководство разбирает корректные таймстемпы, цели на перцентилях и ловушки, порождающие убедительно выглядящие, но неверные измерения.
Что вы на самом деле измеряете
Задержка — не одно число. Письмо проходит сегменты, у каждого свои режимы отказа:
- Приём: время от вызова API отправки вашим приложением до ответа провайдера об успехе.
- Очередь и передача: время внутри провайдера до момента, когда письмо достигает принимающего почтового сервера.
- Видимость во входящих: время от финальной доставки до момента, когда письмо можно забрать.
Одноразовый ящик — точка наблюдения в конце этой цепочки. Вы измеряете время от триггера до видимости во входящих: то число, которое переживают ваши пользователи. Он не раскладывает сегменты за вас. Если нужна разбивка, дополните измерения в ящике событийными вебхуками провайдера — accepted, delivered, bounced — и коррелируйте их по ID письма.
Также понимайте, чем это не является: тестом доставляемости. Попадает ли письмо в спам у крупного потребительского провайдера — вопрос репутации отправителя, и одноразовый домен мало что о нём говорит. Тестирование задержки с временными ящиками измеряет скорость вашего конвейера, а не его репутацию.
Сначала наведите порядок с таймстемпами
Большинство цифр о задержке портится до всякой математики:
- Заголовок Date — не время отправки. Он ставится при компоновке письма, иногда со сбитыми часами, и может предшествовать реальному вызову API. Никогда не считайте разность относительно него.
- Заголовки Received дрейфуют. Каждый прыжок ставит свои часы, часто с точностью до секунды. Используйте цепочки Received для криминалистического порядка, но не для точных дельт — анализатор заголовков писем делает их читаемыми, но времена считайте приблизительными.
- Опрос квантует всё. Опрашивайте каждые пятнадцать секунд — и каждое измерение округляется вверх до следующего опроса; ваш p50 становится кратным интервалу. Опрашивайте чаще или подпишитесь на прибытие через вебхуки.
- Смешанные часы. Записывайте старт и финиш с одной машины по монотонным часам, храните в UTC с миллисекундной точностью.
Измерение, которое переживает ревью: t0 — момент, когда ваш тест запускает отправку; t1 — момент, когда ваш код впервые видит письмо. Одни часы, одно определение, без заголовков.
Повторяемый workflow измерения задержки
1. Готовьте свежий ящик на каждую итерацию. [Создайте временный ящик](/) для ручных проверок или подготавливайте программно, чтобы каждый прогон был изолирован. Песочница API позволяет отрепетировать вызовы до встраивания в CI. 2. Записывайте t0 непосредственно перед триггером. Запускайте отправку регистрации, сброса пароля или 2FA из того же процесса, который фиксирует таймстемп. 3. Подпишитесь на прибытие вместо ожидания. Направьте поток на приёмник вебхуков вроде тестировщика вебхуков, чтобы t1 был событийным. Если без опроса не обойтись — тесный интервал с жёстким дедлайном. 4. Повторите для настоящей выборки. Один прогон не говорит ничего. Гоняйте минимум двадцать итераций на поток на окружение, распределённые по времени, а не подряд. 5. Считайте перцентили, не средние. Отчитывайтесь p50, p95 и max и проверяйте против явного SLO — например, p95 прихода OTP до десяти секунд. Детали по потокам разобраны в статье временная почта для кодов подтверждения. 6. Логируйте ID писем с каждым замером, чтобы выбросы позже можно было проследить через события провайдера.
Программные паттерны разобраны в статье автоматизация тестирования писем через API; прибытие по подписке — в статье тестирование почты с вебхуками.
Читайте цифры как инженер
- Средние прячут хвост, а хвост — это опыт, который вы защищаете. Отчитывайтесь перцентилями или не отчитывайтесь вовсе.
- Уважайте размер выборки: p95 по двадцати замерам близок к вашему худшему наблюдению. Помечайте перцентили малых выборок как индикативные.
- Дисперсия важнее медианы. p50 в три секунды при p95 в сорок указывает на голодание очереди, штормы повторов или троттлинг провайдера — это другой баг, чем равномерная медленность.
- Сравнивайте сопоставимое: пути «первая отправка дня» отличаются от прогретых из-за DNS-кэшей, переиспользования соединений и холодных стартов у serverless-отправителей.
- Держите нагрузочные тесты подальше от окружения, в котором замеряете. Собственный всплеск трафика может спровоцировать троттлинг и раздуть задержку для всех, включая ваш следующий прогон.
Ложные срабатывания, за которыми следить
- Штормы повторов: нетерпеливый тест или фронтенд отправляет повторно, пока первое письмо ещё в пути, наслаивая доставки и искажая последующие наблюдения.
- Последовательное заражение: долбёжка одного адреса может включить перечёшки-троттлинг на получателя у провайдера, раздувая поздние замеры. Свежий ящик на итерацию — ровно то, почему одноразовые адреса бьют общий тестовый ящик в работе с задержками.
- Смещение дедлайна: если тест таймаутится на шестидесяти секундах, а вы усредняете только завершённые прогоны, вы молча выкинули худшие случаи. Считайте таймауты цензурированными данными на границе дедлайна.
- Баги таймзон в агрегации: смешение локального времени и UTC при группировке по часам создаёт фантомные суточные паттерны, на которые тратится реальное время отладки.
Частые вопросы
Какая задержка нормальна для транзакционных писем? Универсального числа нет. Команды обычно держат внутренние SLO в несколько секунд на p95 для писем типа OTP, но правильная цель вытекает из терпения ваших пользователей и ваших же трендовых данных. Установите SLO, измеряйте против него, корректируйте осознанно.
Почему мои замеры кучкуются на кратных интервалу опроса? Потому что опрос квантует прибытие: письмо, пришедшее через секунду после опроса, видно только на следующем. Это артефакт измерения, а не задержка. Переходите на вебхуки или гораздо более тесный интервал.
Сколько нужно замеров? Десятки для смоук-сигнала; больше, когда нужно доверять p95. Распределяйте по времени — двадцать отправок за одну секунду проверяют поведение при всплеске, а не установившуюся доставку.
Может ли тест задержки гейтить CI? Да, с осторожностью: гейт на пороге перцентиля по выборке, никогда по одному прогону; держите пороги достаточно свободными, чтобы избежать флаки-сборок; исключайте окружения, общие с нагрузочными тестами.
Итог
Относитесь к задержке доставки как к задержке API: точные таймстемпы от одних часов, событийное наблюдение, свежий ящик на итерацию, честные перцентили и SLO, которые вы реально проверяете. Временные ящики делают точку наблюдения дешёвой; дисциплина — на вас. Измеряйте время от триггера до видимости, отчитывайтесь p50 и p95 и исследуйте хвост — именно там пользователи тихо сдаются.
