Introduction
Imagine you are an engineer at an e-commerce company with 10 million users. Every month, the marketing team wants to send newsletters to the entire user base. Every time there is a flash sale, millions of emails need to be sent within a few hours. How do you design the system to handle this volume?
This lesson will help you understand the problem before starting to design.
1. Why is Email Notification still important?
Email is the number 1 communication channel
| Metrics | Push | SMS | |
|---|---|---|---|
| Global users | 4.5 billion | 3.5 billion | 5 billion |
| Average open rate | 20-25% | 5-8% | 95% |
| Cost per message | $0.0001-0.001 | Free | $0.01-0.05 |
| Rich content | ✅ HTML, images | ❌ Limited | ❌ Text only |
| No app needed | ✅ | ❌ | ✅ |
Actual Use Cases
Transactional Emails (real-time, critical):
- Order confirmation email
- OTP/Password reset
- Invoice / Receipt
Marketing Emails (batch, high-volume):
- Weekly newsletter
- Flash sale announcements
- Product recommendations
- Re-engagement campaigns
System Notifications:
- Alerting for DevOps team
- Scheduled reports
- Compliance notifications
2. Analyze Requirements
Functional Requirements
FR-1: Hệ thống phải gửi được email đến danh sách recipients
FR-2: Hỗ trợ email templates với dynamic content (personalization)
FR-3: Scheduling: gửi ngay hoặc đặt lịch gửi
FR-4: Tracking: open rate, click rate, bounce rate
FR-5: Unsubscribe management (CAN-SPAM compliance)
FR-6: Multi-provider support (failover giữa các ESP)
FR-7: Priority levels: critical > high > normal > low
Non-Functional Requirements
NFR-1: Throughput: gửi 10 triệu email trong 4 giờ (~700 emails/giây)
NFR-2: Latency: transactional email < 30 giây từ trigger đến delivery
NFR-3: Availability: 99.95% uptime
NFR-4: Durability: không mất email đã queued
NFR-5: Scalability: horizontal scaling khi load tăng
NFR-6: Deliverability: inbox placement rate > 95%
3. Back-of-the-Envelope Estimation
Throughput Calculation
Target: 10 triệu emails trong 4 giờ
= 10,000,000 / (4 × 3,600)
= 10,000,000 / 14,400
≈ 694 emails/giây
Peak (2x): ~1,400 emails/giây
With headroom (3x): ~2,100 emails/giây
Storage Estimation
Email metadata per record: ~1 KB
- recipient, subject, status, timestamps, tracking IDs
10 triệu emails × 1 KB = 10 GB metadata/campaign
Giữ 90 ngày history: 10 GB × 30 campaigns = 300 GB
Template storage: ~100 KB/template × 1000 templates = 100 MB
Total: ~300 GB database storage
Bandwidth Estimation
Average email size (rendered HTML): ~50 KB
10 triệu × 50 KB = 500 GB outbound/campaign
Throughput: 500 GB / 4 hours = 125 GB/h ≈ 280 Mbps
4. Challenges when sending large-scale emails
Technical Challenges
- Rate Limiting from ESP: Amazon SES limit 200 emails/second (default), SendGrid 10,000/second
- IP Reputation: Sent too fast → marked as spam
- Bounce Handling: Hard bounce needs to be removed from the list immediately
- Connection Management: SMTP connection pooling for performance
- Memory Pressure: Load millions of records into memory
Business Challenges
- Deliverability: Email must reach the inbox, not the spam folder
- Compliance: CAN-SPAM, GDPR, CCPA
- Cost: Optimize costs when sending millions of emails
- Timing: Send in the correct timezone, at the optimal time
- Personalization: Different content for each recipient
5. Architecture comparison: Naive vs Production
❌ Naive Approach
for each recipient in 10_million_list:
render_template(recipient)
send_email_via_smtp(recipient)
save_to_database(status)
Problem:
- Sequential → lost 10 million × 0.5s = ~58 days 😱
- Single point of failure
- Do not retry when failing
- Memory overflow when loading the entire list
✅ Production Approach (Preview)
API Request → Notification Service → Message Queue
→ Worker Pool (N workers) → Email Providers (multi-provider)
→ Webhook callbacks → Status tracking → Analytics
We will deep dive into this architecture in the next article.
6. Notification System Landscape
Famous Notification systems
| System | Scale | Tech Stack |
|---|---|---|
| Gmail/Google | 300 billion emails/day | Custom infrastructure |
| Amazon SES | 10+ billion/day | AWS native |
| SendGrid (Twilio) | 100+ billion/month | Kafka, Go, Redis |
| Mailchimp (Intuit) | 600 million/day | Custom, Mandrill |
Open-source alternatives
- Postal - mail delivery platform (Ruby)
- Mailtrain - self-hosted newsletter (Node.js)
- Listmonk - newsletter & mailing list (Go)
- Novu - notification infrastructure (TypeScript)
Summary
In this article, you have learned:
- Why is the problem of sending millions of emails not simple?
- Functional & non-functional requirements
- Back-of-the-envelope estimation
- Challenges need to be resolved
- Preview production architecture
Next article: We will design the High-Level Design architecture for the entire system.