Nunca percorra 1M de usuários em um handler de requisição — distribua o trabalho através de uma fila (fan out), limite a taxa ao que cada provedor consegue aceitar, torne cada envio idempotente e roteie falhas para uma DLQ para retry. A chamada de API apenas enfileira; os workers fazem o I/O lento.
Arquitetura
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
