Как настроить rate limit для SMS API, чтобы оператор не заблокировал канал

Rate limit — это ограничение на количество сообщений, которые вы отправляете за единицу времени. Если превысить порог оператора, канал заблокируют: сначала временно, потом — надолго. Статья покажет, как рассчитать безопасную частоту отправки, настроить очередь на стороне приложения и вовремя заметить, что вы приближаетесь к лимиту. Всё применимо и к HTTP API, и к SMPP-подключению.
Почему оператор блокирует SMS-канал?
Оператор следит за трафиком в реальном времени. Когда с одного отправителя приходит поток сообщений выше допустимого, система расценивает это как спам или техническую ошибку. Триггеры блокировки: превышение лимитов частоты, спам-жалобы от абонентов, несоответствие зарегистрированного альфа-имени и запрещённый контент (по данным smsblog.ru). Блокировка бывает мягкой — оператор начинает дропать часть сообщений без уведомления — и жёсткой, когда канал отключают полностью.
Мягкая блокировка коварнее. Вы продолжаете отправлять, платите за каждое сообщение, а до абонентов доходит 40–60 % трафика. Без мониторинга delivery rate такую ситуацию можно не заметить неделями.
Как рассчитать безопасный rate limit?
Точные лимиты зависят от оператора и типа подключения. Транзакционные SMS (коды подтверждения, статусы заказов) обычно допускают более высокую частоту, чем рекламные рассылки. Вот ориентиры для расчёта:
| Параметр | HTTP API | SMPP |
|---|---|---|
| Типичный старт | 5–10 сообщений/сек | 10–30 сообщений/сек |
| Контроль на стороне оператора | По IP и учётной записи | По bind-сессии и альфа-имени |
| Сигнал превышения | HTTP 429 (Too Many Requests) | ESME_RTHROTTLED (0x00000058) |
| Что делать при сигнале | Пауза + экспоненциальный back-off | Уменьшить окно неподтверждённых PDU |
Перед запуском рассылки запросите у агрегатора или оператора конкретное значение TPS (transactions per second). Не полагайтесь на «примерно так же, как у всех». Один агрегатор даёт 20 TPS на старте, другой — 5. Разница в четыре раза, и с первым же промо-рассылочным пиком вы эту разницу почувствуете.
Как реализовать очередь и throttling в приложении?
Ограничивать скорость нужно на вашей стороне, до отправки в шлюз. Три рабочих подхода:
- Token bucket. Вы «выдаёте» себе фиксированное число токенов в секунду. Каждое сообщение забирает один токен. Токены кончились — сообщение ждёт в очереди. Реализация есть в стандартных библиотеках большинства языков.
- Sliding window. Считаете количество отправленных сообщений за последние N секунд. Если счётчик достиг лимита, новые сообщения встают в очередь. Подход хорош для SMPP, где вы и так контролируете окно неподтверждённых операций.
- Очередь с приоритетами. Транзакционные SMS (OTP, подтверждения) получают высокий приоритет и отправляются первыми. Рекламные — ждут, если канал загружен. Подробнее о приоритизации трафика написано в статье про настройку очереди SMS с rate limit и приоритетами.
В SMPP-протоколе скорость регулируется ещё и размером окна (window size) — количеством PDU, отправленных без подтверждения. Если выставите окно 50, а оператор ожидает не больше 10, часть сообщений вернётся с ошибкой throttling. Перед запуском под реальной нагрузкой протестируйте поведение при пиковом потоке, обрыве и повторном подключении (по рекомендациям quicktel.ru).
Что делать, когда лимит всё-таки превышен?
Получили HTTP 429 или ESME_RTHROTTLED — не повторяйте запрос мгновенно. Каждый повторный запрос в момент throttling ухудшает репутацию отправителя. Алгоритм:
- Зафиксируйте событие в логе с меткой времени и correlation ID.
- Выдержите паузу: 1 секунда → 2 → 4 → 8 (экспоненциальный back-off с потолком 30–60 секунд).
- Если за пять попыток канал не разблокирован, переключитесь на резервный маршрут или уведомите дежурного.
Для HTTP API отслеживайте код ответа, время выполнения, таймауты и долю неуспешных запросов. На уровне приложения correlation ID должен проходить через CRM, очередь и шлюз, чтобы вы могли восстановить путь конкретного сообщения (по данным smpp.by). Подробнее о том, как вести себя при устойчивом превышении лимитов, — в материале про graceful degradation SMS-рассылки.
Типичные ошибки при настройке rate limit
- Нет очереди вообще. Приложение шлёт сообщения с той скоростью, с которой их генерирует. При акции или массовой промо-рассылке канал «ложится» за минуты.
- Одинаковый приоритет для всех SMS. OTP-код для входа в личный кабинет стоит в одной очереди с уведомлением об акции. Клиент ждёт код 40 секунд, уходит и не возвращается.
- Retry без back-off. Сообщение не ушло — система повторяет его 10 раз за секунду. Оператор видит всплеск и ужесточает ограничения.
- Игнорирование delivery receipt. Вы не запрашиваете DLR и не знаете, сколько сообщений реально дошло. Проблема с лимитом становится видна, только когда клиенты звонят в поддержку.
- Жёстко зашитый лимит. Оператор изменил TPS, а ваш код по-прежнему шлёт с прежней скоростью. Лимиты стоит вынести в конфиг или переменные окружения.
Как мониторить, что всё работает?
Минимальный набор метрик для дашборда:
- Текущий TPS (факт vs. установленный лимит).
- Доля ответов с throttling-ошибками за последние 5 минут.
- Delivery rate за час и за сутки.
- Средняя длина очереди и время ожидания сообщения.
Для SMPP-сессии добавьте контроль enquire_link: клиент регулярно отправляет heartbeat, контролирует ответ enquire_link_resp и переподключается после таймаута (по данным smpp.by). Если heartbeat не вернулся за 30–60 секунд, сессия, скорее всего, потеряна, и дальнейшие submit_sm уйдут в пустоту. Чтобы дубли не уходили при переподключении, проверьте, как у вас устроена идемпотентность SMS API.
Три шага, которые стоит сделать на этой неделе:
- Запросите у агрегатора точное значение TPS для вашего альфа-имени и типа трафика — 10 минут на письмо или звонок.
- Добавьте в код token bucket или sliding window с лимитом на 80 % от разрешённого TPS (запас на всплески) — 2–4 часа работы разработчика.
- Настройте алерт на долю throttling-ошибок выше 1 % за 5 минут — полчаса на подключение к любой системе мониторинга.


