← Back to Case Studies
High-volume

Sending 1 Million Emails in 25 Minutes

High-Performance Mautic on AWS

1M
Emails sent
25 min
Total time
~40k
Emails per minute
52
Parallel workers

The client operates a SaaS platform with white-labeled marketing automation powered by Mautic. As the platform grew to support hundreds of tenants sending campaigns simultaneously, the default Mautic email sending pipeline — processing contacts one-by-one — became a critical bottleneck. We needed to fundamentally rethink how emails are batched, queued, and dispatched.

Performance Results

Emails sent1,000,000
Time25 minutes
Throughput~40,000 emails/minute
Parallel workers~52 during stress test
Batch size1,000 recipients per Mailgun API call
Queue stages2 (segment scan → payload assembly → dispatch)
Stage 1 durationSeconds (ID batching only)
PersonalizationPer-recipient dynamic content (branch, location, images)

The Challenge

1Send 1 million+ personalized emails in under 30 minutes
2Dynamic content personalization per recipient (branch-specific footers, images, contact details)
3Maintain high email deliverability and sender reputation
4Handle SQS message size limits causing failures with standard payloads
5Process bounce notifications from Mailgun and route to correct tenant
6Keep infrastructure cost-efficient using spot instances

The Pipeline

Stage 1 — Segment Scanning

Milliseconds to batch millions

Fetches the full contact list, creates lightweight batches of contact IDs, and pushes them to the first SQS queue. Completes in seconds — even for millions of contacts.

Stage 2 — Payload Assembly

52 parallel workers

Workers pull contact ID batches, load full contact data, resolve personalization tokens, build Mailgun payloads. Each worker handles roughly one batch per minute.

Dispatch — Mailgun Batch API

1,000 recipients per API call

Mailgun receives a template with placeholder tokens and up to 1,000 recipients per call. A batch of 1,000 emails becomes a single API request — not 1,000 separate requests.

Engineering Challenges We Solved

Custom SQS + S3 Transport

AWS SQS has a strict 256 KB payload limit. Email batch payloads with 1,000 recipients easily exceed this. Our solution:

1.When payload exceeds the SQS limit, it's written to S3
2.SQS message contains only a reference to the S3 object
3.Consumer detects the reference, downloads from S3, and processes normally

Built as a custom transport based on the Symfony Messenger SQS Bridge.

Intelligent Bounce Handling

All tenants share a single Mailgun sending domain. Bounce notifications need to reach the correct tenant. Rather than unreliable webhooks, we built a crawler-based approach:

  • Periodically polls the Mailgun API for bounce records
  • Each email includes a custom header with the tenant identifier
  • Routes bounce data to the correct Mautic instance
  • Handles both hard bounces and soft bounces

Graceful Processing Under Spot Interruptions

Workers run on AWS spot instances for cost efficiency, but spot instances can be reclaimed with only minutes' notice. Our safeguards:

  • Graceful shutdown signals — workers get 1-2 min to finish current batch
  • Proper SQS connection cleanup prevents ambiguous message states
  • Force kill fallback returns unprocessed messages to queue

Email Deduplication & Queue Priority

Real-time deduplication ensures only one email per unique address within a campaign — even across batches processed by different workers. Queue priority rules ensure fully assembled batches are always dispatched first, keeping the pipeline flowing under heavy load from simultaneous campaigns.

0
Emails in 25 minutes
0
Emails per minute
0
Parallel workers
0
Emails lost

Business Impact

Lower costs than projected — spot instances and intelligent queue management
Deliverability protected — API-based bounce crawler ensures sender reputation across all tenants
Zero email loss — graceful shutdown, queue retry, real-time deduplication
Custom SQS+S3 transport overcomes AWS queue size limitations transparently
Scalable for growth — supports roadmap to 300-500 tenants sending simultaneously

Technology Stack

Email Service
Mailgun (batch APItemplate tokenization)
Queue System
AWS SQScustom S3 payload offloading
Application
PHP/SymfonyMauticMessenger component
Storage
AWS S3 (large payloads)FSx (shared filesystem)
Orchestration
Kubernetes (EKS)Carpenter (autoscaling)
Infrastructure
AWS spot instancescost-efficient processing
Monitoring
GrafanaPrometheus

Need High-Performance Email at Scale?

Let's discuss your email infrastructure and performance goals.