Рассылка на 200 000 адресов: что будет с сайтом через 90 секунд
Кнопка «Отправить» в сервисе рассылок нажата, письма ушли на 200 000 адресов — для маркетинга задача выполнена, а для сервера она только начинается. Первые полторы минуты после массовой отправки — это не плавный рост трафика, к которому сервер привык в обычные дни, а резкий синхронный всплеск: тысячи людей открывают почти одинаковое письмо в одну и ту же минуту и переходят по одной и той же ссылке. Разберём, что происходит в эти 90 секунд, чем это отличается от обычного трафика и какие меры реально держат посадочную страницу на ногах.
Содержание
Что происходит в первые 90 секунд после отправки
Даже хороший ESP редко отправляет всю базу одномоментно — он ставит письма в очередь к SMTP-серверам получателей и распределяет отправку по пулу IP, чтобы не спровоцировать спам-фильтры. Но с точки зрения получателя это почти неважно: почтовый ящик обрабатывает входящий поток от знакомого отправителя пачками, и разброс по факту составляет секунды, а не часы.
Дальше идут два параллельных процесса, которые сервер видит как одну и ту же нагрузку на один и тот же URL.
Первый — автоматическое сканирование ссылок. Крупные почтовые провайдеры проверяют ссылки в письме ещё до того, как человек его открыл: Microsoft 365 с Safe Links сканирует URL сразу при доставке, антивирусные прокси корпоративных шлюзов делают то же самое, Gmail проксирует картинки из письма через свои серверы. В первые секунды после доставки на посадочную страницу приходит волна запросов с IP дата-центров почтовых провайдеров, а не от читателей — но она полноценно грузит TCP-соединения, TLS-хендшейк и рендеринг страницы.
Второй, более заметный процесс — реальные открытия. Люди проверяют почту не равномерно в течение дня, а пачками: обед, начало рабочего дня, вечер. Если рассылка ушла в момент, когда часть аудитории и так открывает почту, письмо попадает в свежий верх списка входящих и получает основную долю открытий именно в первые минуты — дальше внимание переключается на следующее письмо, и кривая открытий резко проседает.
Сложите оба процесса — и получится не плавный рост, а скачок нагрузки на конкретный URL в конкретную минуту, происходящий синхронно у тысяч независимых людей и ботов.
Почему это не похоже на обычный органический трафик
Разница не только в скорости роста, но и в структуре запросов — и именно это ломает интуицию тех, кто привык мерить нагрузку в терминах «сайт держит X запросов в секунду в среднем».
Органический трафик — из поиска, соцсетей, прямых заходов — размазан по множеству разных страниц, кеш каждой прогревается постепенно, а даже дневной пик нарастает за десятки минут, оставляя время автоскейлингу среагировать. Трафик из рассылки устроен ровно наоборот:
- Один URL. Все 200 000 писем ведут на одну и ту же посадочную страницу (в лучшем случае — на несколько вариантов A/B-теста). Весь удар приходится не на инфраструктуру в среднем, а на один код пути: один маршрут, один запрос к базе, один кеш-ключ.
- Одна секунда. Всплеск концентрируется в узком окне, а не растягивается на часы. Автоскейлинг реагирует на возросшую нагрузку с задержкой в минуты — новый инстанс поднимется тогда, когда пик уже прошёл.
- Холодный кеш в момент максимальной нагрузки. Если страницу не открывали последние сутки, TTL истёк, и первый запрос после рассылки — это не одиночный визит, а сразу тысяча параллельных запросов, синхронно промахивающихся мимо кеша в origin. Это классический thundering herd, только спровоцированный не рестартом кеша, а маркетинговой кампанией с заранее известным временем старта — механика та же, что в статье про эффект стада при прогреве кеша.
- Похожие паттерны у получателей. Если рассылка ушла преимущественно на несколько крупных почтовых доменов, у каждого свой ритм проверки писем и своя аудитория с похожими привычками — совпадение по времени внутри одного провайдера усиливает пик, а не сглаживает его.
Практический вывод: тестировать сайт нагрузочным тестом «столько-то RPS в среднем за час» для рассылки бессмысленно. Нужен тест именно на короткий пиковый всплеск запросов к одному URL, а не на растянутую по часу равномерную нагрузку.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверСканеры почтовых провайдеров: невидимая часть нагрузки
Сканирование ссылок часто забывают учесть при подготовке к рассылке, хотя оно бьёт по серверу раньше живых пользователей. Если в письме есть трекинговая ссылка (а в массовых рассылках она есть почти всегда — сервис подменяет прямую ссылку на редирект через свой домен для подсчёта кликов), сканер проходит по цепочке редиректов до конечной страницы, полностью её загружая. С точки зрения сервера это неотличимо от обычного визита, кроме одного: User-Agent и диапазон IP часто выдают дата-центр вместо домашнего интернета.
Что это значит практически:
- Часть нагрузки в первые секунды после отправки — это не будущие клиенты, а автоматические проверки. Игнорировать её нельзя: она реальна для сервера, даже если не даёт конверсий.
- Одно письмо может быть просканировано несколько раз — разными сервисами защиты (антиспам, антивирус, DLP) на одном и том же корпоративном домене. При базе с заметной долей корпоративных адресов это ощутимо увеличивает первую волну сверх числа реальных подписчиков.
- Сканеры обычно не выполняют JavaScript и не заходят дальше первой страницы, поэтому не нагружают формы и API — весь удар приходится на статическую отдачу лендинга. Хорошая новость: то же кеширование, которое спасает от реальных пользователей, полностью гасит и эту волну.
Точной доли такого трафика заранее не предсказать — она зависит от состава базы. Ориентируйтесь на логи прошлых рассылок: запросы с IP крупных облачных провайдеров и характерными User-Agent антивирусных прокси в первые секунды после отправки — это она.
Кеш посадочной страницы: что и как кешировать
Первая и самая эффективная линия обороны — не пускать всплеск дальше веб-сервера. Если посадочная страница отдаётся из кеша nginx, для origin-приложения и базы 200 000 открытий выглядят как несколько запросов в минуту — ровно столько, сколько нужно, чтобы обновлять кеш.
Базовая схема nginx как обратного прокси перед приложением:
proxy_cache_path /var/cache/nginx/landing levels=1:2 keys_zone=landing_cache:20m max_size=1g inactive=60m use_temp_path=off;
server {
listen 443 ssl;
server_name promo.example.com;
location /campaign/ {
proxy_pass http://app_backend;
proxy_cache landing_cache;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 10m;
proxy_cache_valid 404 1m;
# ключевая настройка против стада запросов на промахе кеша
proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
# отдавать устаревшую версию, пока обновляем в фоне
proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
proxy_cache_background_update on;
add_header X-Cache-Status $upstream_cache_status;
}
}
Три директивы здесь решают именно проблему синхронного всплеска:
proxy_cache_lock— при промахе кеша к origin уходит только один запрос, остальные параллельные запросы к тому же URL ждут его ответа и получают тот же результат из кеша. Без неё тысяча одновременных запросов к холодному кешу превращается в тысячу одновременных запросов к базе — тот самый эффект стада.proxy_cache_use_stale updating— пока идёт обновление кеша, посетители получают чуть устаревшую, но валидную страницу вместо ожидания или ошибки.proxy_cache_valid— держите TTL достаточно длинным для страницы, которая не меняется в реальном времени. Слишком короткий TTL — частая причина, почему «кеш вроде настроен, а сервер всё равно упал».
Важный нюанс: кешировать целиком можно только то, что одинаково для всех посетителей. Если на странице есть персонализация — имя из письма, реферальный код, счётчик остатка мест — вынесите её в отдельный лёгкий запрос с собственным, более коротким кешем, а не отключайте кеш всей страницы целиком.
Отдельный лендинг вместо страницы на боевом сайте
Вторая мера — архитектурная, и она важнее, чем кажется: страница, на которую ведёт массовая рассылка, не должна жить в том же приложении и на той же базе, что личный кабинет, оформление заказа или админка.
Причина простая: даже идеально настроенный кеш не спасает на сто процентов — будут запросы мимо кеша (первый визит на новый вариант A/B-теста, сброс кеша при деплое во время рассылки, поисковые боты, подхватившие свежий URL). Если посадочная страница крутится в общем пуле процессов с основным сайтом, всплеск на ней съедает воркеры и соединения к базе, которые в этот момент нужны действующим клиентам. Получается парадокс: маркетинговая кампания, призванная привлечь новых клиентов, на 90 секунд кладёт покупку у уже привлечённых.
Практическая изоляция выглядит так:
- Посадочная страница рассылки — отдельный статический билд или лёгкое приложение, часто на поддомене (
promo.example.comвместоexample.com/promo), с собственным пулом соединений и, если возможно, отдельным сервером или контейнером. - Кнопка на этой странице ведёт на основной сайт уже вторым переходом — первый удар трафика принимает лёгкая статическая страница, а до тяжёлой логики (авторизация, каталог с запросами к базе, оформление заказа) доходит уже отфильтрованная и распределённая во времени часть аудитории.
- Если посадочная страница технически всё равно часть основного сайта, убедитесь хотя бы, что у неё отдельный upstream или лимит соединений в nginx, чтобы всплеск на ней не забирал ресурсы у остального сайта.
Отдельный лендинг проще всего поднять на собственном VPS, не завязанном на инфраструктуру основного продакшена — тогда даже отказ этой страницы под нагрузкой не затронет ничего критичного. Пошаговая настройка такого изолированного лендинга разобрана в статье «Лендинг на своём сервере на VPS с нуля».
Прогрев CDN перед отправкой, а не после
Если посадочная страница отдаётся через CDN — а для рассылки на 200 000 адресов это стоит делать почти всегда, чтобы разнести нагрузку географически, — остаётся последняя ловушка: каждый эдж CDN кеширует независимо и холоден до первого запроса из своего региона. Если первых посетителей из-за синхронного открытия рассылки сразу тысяча, получится тот же thundering herd, что и на уровне nginx, только размноженный на все эджи сразу.
Решение — прогреть кеш заранее, до отправки писем:
- За 10-15 минут до отправки вручную сделайте запрос к посадочной странице через каждый значимый эдж CDN (большинство провайдеров позволяют адресовать конкретный PoP или предоставляют API для принудительного прогрева кеша).
- Проверьте заголовок ответа, показывающий статус кеша CDN (
CF-Cache-Status,X-Cacheили аналог) — на прогревающем запросе должно бытьMISS, на повторном —HIT. Если повторный запрос всё ещё промахивается, TTL кеша слишком короткий либо в URL есть уникальный параметр (например, тот же трекинговый код), из-за которого CDN считает каждый визит новым — частая причина, разобранная в статье «CDN поставили, а быстрее не стало». - Пример прогрева нескольких эджей вручную (замените адреса на реальные эндпоинты вашего CDN):
#!/usr/bin/env bash
URL="https://promo.example.com/campaign/offer/"
EDGES=("edge-eu.example-cdn.net" "edge-us.example-cdn.net" "edge-asia.example-cdn.net")
for edge in "${EDGES[@]}"; do
echo "Прогрев $edge:"
curl -s -o /dev/null -w " status=%{http_code} time=%{time_total}s\n" \
--resolve "promo.example.com:443:$(dig +short $edge | head -1)" \
"$URL"
done
- Держите TTL кеша на CDN заведомо длиннее окна активных открытий письма, чтобы кеш не остыл в середине этого окна.
- Если рассылка идёт волнами (по часовым поясам или сегментам аудитории), прогревайте кеш перед каждой волной отдельно — TTL мог истечь между волнами, и следующая волна получит холодный старт точно так же, как первая.
Дополнительно стоит закрыть ещё пару пунктов: смоделировать в нагрузочном тесте именно резкий всплеск за 30-60 секунд, а не растянутую нагрузку; поставить отдельный limit_req в nginx на форму или счётчик мест, если они есть на странице, — сама страница спасётся кешем, а запись в базу кешем не закроешь; и предупредить хостинг заранее, если ожидаете экстремальный всплеск, — иначе легитимный синхронный трафик рискует попасть под защиту от DDoS.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Нужно ли постоянно держать посадочную страницу на мощном сервере ради полутора минут пиковой нагрузки раз в квартал?
Нет — тяжёлая часть работы, обслуживание кеша, не требует мощного сервера, потому что при правильной настройке origin отвечает лишь на единицы запросов в минуту, а не на весь всплеск. Отдельный лендинг на скромном VPS дешевле и безопаснее, чем масштабирование основного продакшена под редкий пик.
CDN сам не прогреется от реальных посетителей за первые секунды?
Прогреется, но с задержкой и через кеш-промах у первых посетителей каждого региона — именно те, кто открыл письмо быстрее всех, получат самый медленный ответ, а при синхронном открытии тысячами это ещё и стадный эффект на origin. Ручной прогрев снимает проблему до того, как её увидят живые люди.
Как отличить сканеры почтовых провайдеров от реальных пользователей в логах?
По User-Agent и диапазону IP — сканеры крупных почтовых сервисов и антивирусных прокси обычно приходят с известных диапазонов облачных провайдеров и приходят почти мгновенно после отправки, в разы быстрее, чем успел бы отреагировать живой человек.
Что если посадочная страница содержит форму регистрации, а не просто статичный контент?
Разделите страницу на статичную оболочку (кешируется целиком и агрессивно) и форму, которая обращается к отдельному лёгкому API-эндпоинту с собственным лимитом запросов — так закешируется большая часть страницы, а лимитом защищена только реально уязвимая часть, пишущая в базу.
На сколько заранее нужно прогревать CDN перед отправкой?
Обычно достаточно 10-15 минут — этого хватает, чтобы прогревающий запрос дошёл до эджей, origin успел ответить и закешироваться, а кеш не успел истечь до реальной отправки. Если TTL на CDN короче, либо увеличьте его для этой страницы, либо прогревайте ближе к моменту отправки.
Рассылка идёт несколькими волнами по сегментам — нужно прогревать каждый раз?
Да, если между волнами проходит больше времени, чем TTL кеша. Проще всего либо синхронизировать TTL с интервалом между волнами, либо прогревать кеш перед стартом каждой волны — это дешевле, чем разбираться с промахами кеша в проде.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →