Никогда не перебирайте 1 млн пользователей в обработчике запроса — разложите работу через очередь (fan-out), ограничивайте темп тем, что готов принять каждый провайдер, делайте каждую отправку идемпотентной и направляйте сбои в DLQ для повторов. Вызов API только ставит задачи в очередь; медленный I/O выполняют воркеры.
Архитектура
Admin ─▶ Campaign API ─▶ [enqueue job] ─▶ Kafka/SQS ─┐
▼
┌──────────────── Worker pool (autoscaled) ───────────────┐
│ claim ─▶ dedup(Redis SETNX) ─▶ rate-limiter ─▶ provider │
└──────────┬──────────────────────────────┬───────────────┘
│ ok │ fail (5xx/timeout)
▼ ▼
sent_log (DB) Retry (backoff) ─▶ DLQ
