Ne parcourez jamais 1M d'utilisateurs dans un gestionnaire de requête — répartissez la charge (fan out) via une queue, limitez le débit à ce que chaque provider peut accepter, rendez chaque envoi idempotent, et routez les échecs vers une DLQ pour réessai. L'appel API ne fait qu'enfiler le travail ; les workers réalisent les I/O lentes.
Architecture
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
