This document presents a scalable email delivery system design that handles high-volume email processing with robust error handling, retry logic, and comprehensive monitoring for enterprise-grade reliability.
1. Executive Summary
Clarifying questions
- What is the expected read/write ratio for email delivery operations? (e.g., 1:100 for sending vs. retrieving)
- What are the consistency requirements for email delivery? (e.g., eventual consistency vs. strong consistency)
- Is the system expected to operate globally or within a single region for now?
- How latency-sensitive is email delivery? (e.g., real-time vs. batch processing acceptable)
- What is the expected growth in email volume and user base over the next 2 years?
- Are there any external integrations required (e.g., SMTP providers, email validation services)?
- What are the primary use cases for email delivery? (e.g., transactional, marketing, notifications)
Problem being solved
Design a highly scalable, fault-tolerant email delivery service that can handle millions of emails per second with low latency and high availability, while ensuring reliable message delivery, proper handling of retries and failures, and compliance with email standards (RFC 5322, SMTP).
Back-of-envelope calculations
-
DAU → Peak QPS: 10M DAU, assuming 10:1 peak-to-average ratio, and 86400 seconds in a day
- Average QPS = 10M / 86400 ≈ 116 QPS
- Peak QPS = 116 × 10 = 1,160 QPS
-
Storage per user/event:
- Avg. email size: 50KB
- Emails per user/year (assuming 1 email/day): 365
- Storage per user/year = 50KB × 365 ≈ 18.25 MB/user/year
-
Bandwidth (read + write throughput):
- Write bandwidth = 1,160 QPS × 50KB ≈ 58 MB/s
- Read bandwidth = Assuming 10% read traffic → 5.8 MB/s
- Total bandwidth ≈ 63.8 MB/s
-
Cache hit rate assumption: 90%
- DB QPS = 1,160 × (1 - 0.9) = 116 QPS
-
Number of servers needed at peak:
- Assuming 500 QPS per server (typical for a well-optimized microservice)
- Servers needed = 116 / 500 ≈ 0.23 servers → Round up to 1 server (for redundancy and future scaling)
SLA targets
- Availability: 99.9% (3.6 minutes downtime/month)
- Latency:
- p50: <200ms
- p95: <500ms
- p99: <1s
- Delivery success rate: >99.5% (with retries and error handling)
Key architectural decisions summary
- Microservices-based architecture for scalability, maintainability, and independent deployment
- Event-driven design with Kafka for asynchronous processing of email delivery tasks
- Multi-region deployment to ensure global availability and low latency
- CQRS pattern for separating read and write operations
- Stateless services to support horizontal scaling and high availability
- Comprehensive observability stack including logging, tracing, and metrics for operational insight
- Secure authentication and authorization using OAuth2/OIDC with service-to-service mTLS
- Fault-tolerant messaging and retry mechanisms to ensure reliable delivery
- Storage tiering strategy with hot/warm/cold storage for cost optimization
- Zero-downtime deployment and rollback strategy using canary releases and feature flags
This design balances performance, reliability, and cost while maintaining flexibility for future enhancements.
2. System Goals & Non-Functional Requirements
Latency Targets
- p50: 100ms for email delivery initiation
- p95: 500ms for email delivery initiation
- p99: 2s for email delivery initiation
- End-to-end email delivery: p50: 2s, p99: 10s (from queue to recipient inbox)
Throughput Requirements
- Average QPS: 10,000 emails/sec (assumes 50M DAU with 20 emails/user/day)
- Peak QPS: 100,000 emails/sec (10x average, 86,400 seconds in a day)
- Email size: 50KB average (including headers, content, attachments)
- Write throughput: 5GB/s peak (100K emails/sec * 50KB)
- Read throughput: 2GB/s peak (for delivery status, metrics, logs)
Availability Target
- 99.9% (3 9s) availability for email delivery service
- Justification: Email delivery is a core business function; 0.1% downtime translates to ~8.6 minutes daily of lost revenue and customer trust
- 99.99% (4 9s) for critical sub-systems like authentication and delivery status monitoring
Durability and Consistency Requirements
- Consistency Model: Eventual consistency for delivery status updates (asynchronous)
- Durability: At-least-once delivery guarantee for email messages to prevent lost emails
- CAP Trade-off: Prioritize availability and partition tolerance over strong consistency (as email delivery is more critical than perfect consistency)
- Data Integrity: Message IDs and timestamps must be immutable once written
Data Retention and Compliance Requirements
- Email retention: 30 days for delivery status, 1 year for analytics and audit logs
- Compliance: GDPR compliance for EU users (data portability, right to deletion)
- Audit logging: Full audit trail of email delivery events for 1 year
- Data classification: User content is classified as "sensitive" with encryption in transit and at rest
Security and Regulatory Requirements
- Encryption: TLS 1.3 for all communications, AES-256 for data at rest
- Authentication: OAuth2/OIDC for service-to-service communication, JWT tokens for API access
- Authorization: RBAC model with granular permissions (send email, view delivery status)
- Regulatory: HIPAA compliance for healthcare-related emails, SOC2 Type II for general security
- Threat model: DDoS protection, rate limiting, and IP reputation monitoring required
- Secrets management: All secrets (API keys, SMTP credentials) stored in centralized secrets manager with rotation policies
3. High-Level Architecture Diagram
C4Context
title Email Delivery Service - System Context
Person(user, "End User")
Person(admin, "System Administrator")
System_Boundary(b1, "Email Delivery Service") {
System(email_service, "Email Service", "Handles email processing and delivery")
System(queue_service, "Queue Service", "Manages email queues and retry logic")
System(smtp_service, "SMTP Service", "Handles SMTP protocol communication")
System(notification_service, "Notification Service", "Handles push notifications")
System(auth_service, "Auth Service", "Handles authentication and authorization")
System(cache_service, "Cache Service", "Caching layer for frequently accessed data")
System(db_service, "Database Service", "Primary and replica databases")
System(storage_service, "Storage Service", "S3-compatible object storage for attachments")
System(message_broker, "Message Broker", "Kafka for event streaming")
}
System_Ext(smtp_provider, "External SMTP Provider", "Third-party SMTP service")
System_Ext(push_provider, "Push Notification Provider", "Firebase/Apple Push Notification Service")
Rel(user, email_service, "Sends emails via API")
Rel(email_service, queue_service, "Queues emails for delivery")
Rel(queue_service, smtp_service, "Triggers email delivery")
Rel(smtp_service, smtp_provider, "Relays to external SMTP provider")
Rel(email_service, notification_service, "Sends push notifications")
Rel(notification_service, push_provider, "Relays to push provider")
Rel(email_service, cache_service, "Caches user and template data")
Rel(email_service, db_service, "Stores email metadata and user preferences")
Rel(email_service, storage_service, "Stores email attachments")
Rel(email_service, message_broker, "Publishes events for async processing")
Rel(auth_service, email_service, "Authenticates API requests")
Rel(admin, email_service, "Manages system via admin dashboard")
C4Container
title Email Delivery Service - Container Diagram
Container_Boundary(c1, "Email Delivery Service") {
Container(email_api, "Email API Gateway", "REST API", "Handles incoming email requests")
Container(email_processor, "Email Processor", "Microservice", "Processes email workflows")
Container(email_queue, "Email Queue Service", "Queue Manager", "Manages email delivery queues")
Container(smtp_handler, "SMTP Handler", "Protocol Handler", "Handles SMTP protocol communication")
Container(notification_handler, "Notification Handler", "Push Service", "Handles push notifications")
Container(cache_layer, "Cache Layer", "Redis", "Caching for templates and user data")
Container(db_layer, "Database Layer", "PostgreSQL", "Primary database for email metadata")
Container(storage_layer, "Storage Layer", "S3-compatible", "Object storage for attachments")
Container(event_streamer, "Event Streamer", "Kafka", "Event streaming for async processing")
}
Container_Boundary(c2, "External Systems") {
Container(smtp_provider, "SMTP Provider", "Third-party SMTP", "Relays emails to external providers")
Container(push_provider, "Push Provider", "Firebase/AWS", "Handles push notifications")
}
Rel(email_api, email_processor, "REST calls")
Rel(email_processor, email_queue, "Queues emails")
Rel(email_queue, smtp_handler, "Triggers delivery")
Rel(smtp_handler, smtp_provider, "Relays to SMTP provider")
Rel(email_processor, notification_handler, "Sends push notifications")
Rel(notification_handler, push_provider, "Relays to push provider")
Rel(email_processor, cache_layer, "Caches data")
Rel(email_processor, db_layer, "Stores metadata")
Rel(email_processor, storage_layer, "Stores attachments")
Rel(email_processor, event_streamer, "Publishes events")
UpdateRelStyle(email_api, email_processor, $offsetX=20, $offsetY=-10)
UpdateRelStyle(email_processor, email_queue, $offsetX=20, $offsetY=-10)
UpdateRelStyle(email_queue, smtp_handler, $offsetX=20, $offsetY=-10)
UpdateRelStyle(smtp_handler, smtp_provider, $offsetX=20, $offsetY=-10)
UpdateRelStyle(email_processor, notification_handler, $offsetX=20, $offsetY=-10)
UpdateRelStyle(notification_handler, push_provider, $offsetX=20, $offsetY=-10)
UpdateRelStyle(email_processor, cache_layer, $offsetX=20, $offsetY=-10)
UpdateRelStyle(email_processor, db_layer, $offsetX=20, $offsetY=-10)
UpdateRelStyle(email_processor, storage_layer, $offsetX=20, $offsetY=-10)
UpdateRelStyle(email_processor, event_streamer, $offsetX=20, $offsetY=-10)
Major Components and Services
Core Services:
- Email API Gateway: RESTful API for email submission, tracking, and management
- Email Processor: Main service that orchestrates email workflows, handles templates, and manages delivery logic
- Email Queue Service: Manages email delivery queues with retry logic and dead letter handling
- SMTP Handler: Implements SMTP protocol communication with external providers
- Notification Handler: Manages push notifications for delivery status updates
Data Stores:
- Database Layer: PostgreSQL for email metadata, user preferences, and templates
- Cache Layer: Redis for frequently accessed data (user profiles, templates)
- Storage Layer: S3-compatible storage for email attachments and large content
Event Streaming:
- Event Streamer: Kafka-based event bus for asynchronous processing and cross-service communication
External Integrations:
- SMTP Provider: Third-party SMTP services (SendGrid, Amazon SES, etc.)
- Push Provider: Firebase Cloud Messaging or Apple Push Notification Service
Traffic Flow and Data Flow
- Email Submission: User sends email via API → API Gateway routes to Email Processor
- Queue Management: Email Processor queues emails in Queue Service for delivery scheduling
- SMTP Delivery: Queue Service triggers SMTP Handler → External SMTP Provider
- Notification: Push notifications sent via Notification Handler to Push Provider
- Data Persistence: Email metadata stored in Database, attachments in Storage Layer
- Event Streaming: Events published to Kafka for async processing and observability
- Caching: User and template data cached in Redis for performance optimization
4. Service Architecture
Microservices vs. Monolith vs. Modular Monolith Decision
For an email delivery service, we'll adopt a modular monolith approach as the initial architecture pattern. This decision balances:
- Faster time-to-market: Single deployment unit reduces complexity during initial development
- Easier debugging and testing: All components in one codebase simplify local development and debugging
- Scalability foundation: Modular structure allows for future microservice decomposition without complete rewrite
The modular monolith will be organized into bounded contexts:
- Email Processing Service: Handles email creation, validation, and queuing
- Delivery Service: Manages email delivery to SMTP providers and tracking
- User Management Service: Handles user profiles, preferences, and authentication
- Analytics Service: Processes delivery metrics and engagement tracking
Service Decomposition Strategy
Services will be decomposed by domain boundaries:
-
Email Processing Service (user-facing):
- Email creation, validation, content sanitization
- Template rendering and personalization
- Priority queuing and scheduling
-
Delivery Service (core processing):
- SMTP provider integration and delivery
- Retry logic and delivery status tracking
- Bounce handling and retry policies
-
User Management Service (data layer):
- User profiles, preferences, and consent management
- Email address validation and verification
- Rate limiting and throttling logic
-
Analytics Service (observability):
- Delivery metrics and engagement tracking
- Real-time dashboard integration
- Reporting and alerting
Service Boundaries and Contracts
Each service will maintain clear contracts:
Email Processing Service API:
POST /emails: Create new email with content and recipientsGET /emails/{id}: Retrieve email status and metadataPOST /emails/{id}/resend: Resend failed emails
Delivery Service API:
POST /deliveries: Submit email for delivery to providerGET /deliveries/{id}: Track delivery status and logsPOST /deliveries/{id}/retry: Retry failed deliveries
User Management Service API:
GET /users/{id}: Retrieve user preferences and settingsPUT /users/{id}/preferences: Update email preferencesPOST /users/{id}/validate: Validate email address format
Inter-Service Communication Pattern
Synchronous (REST/gRPC):
- User Management → Email Processing: For user preference validation
- Delivery Service → Email Processing: For delivery status updates
Asynchronous (Event-driven):
- Email Processing → Delivery Service: Email submission event
- Delivery Service → Analytics: Delivery status and engagement events
- User Management → Analytics: User preference change events
Service Mesh Consideration
We'll initially avoid service mesh for the first phase to reduce operational complexity. Service mesh (Istio) will be considered in Phase 3 for advanced observability and traffic management capabilities.
Service Registry and Discovery Strategy
- Service Registry: Consul or Eureka for service discovery
- Health Checks: Liveness and readiness probes on all services
- Load Balancing: Client-side load balancing with circuit breaker pattern
- Versioning: Semantic versioning for API contracts with backward compatibility
Service Design Principles
- Stateless Services: All services designed to be stateless for horizontal scaling
- Idempotent Operations: Delivery and retry operations designed to be idempotent
- Async Processing: Critical workflows use async patterns to improve throughput and resilience
- Service Isolation: Each service owns its data and processing logic independently
Future Microservice Migration Path
The modular monolith design provides a clear migration path to microservices:
- Phase 2: Split Email Processing and Delivery services into separate microservices
- Phase 3: Extract User Management and Analytics as independent services
- Monitoring: Track service dependencies and performance to identify bottlenecks for migration
This approach provides the best balance between rapid development, operational simplicity, and future scalability.
5. Data Architecture
Database Selection per Service
Email Service (Primary)
- Database: PostgreSQL (v14+)
- Justification:
- Structured email data with complex relationships (user, template, campaign, delivery status)
- Strong ACID guarantees required for email delivery tracking and retry logic
- Complex querying needs (analytics, reporting, filtering by status, timestamp ranges)
- Support for JSONB fields for flexible email content storage
- Mature ecosystem with excellent tooling and monitoring capabilities
Email Templates Service
- Database: MongoDB (v6+)
- Justification:
- Template content is primarily document-based with nested structures
- Flexible schema evolution for different template types (HTML, plain text, dynamic content)
- Fast read operations for template retrieval during email generation
- Good performance for aggregation queries on template usage statistics
User Preferences Service
- Database: Redis (v7+)
- Justification:
- High-performance key-value store for user preference caching (opt-in/out, frequency settings)
- TTL-based expiration for temporary preferences
- Atomic operations for preference updates and bulk operations
- Low latency requirement for real-time preference checks
Delivery Metrics Service
- Database: TimescaleDB (v2.10+)
- Justification:
- Time-series data for email delivery metrics (open rates, click rates, bounce rates)
- Efficient storage and querying of time-based event data
- Built-in support for continuous aggregates and rollups
- Integration with Prometheus/Grafana for real-time dashboarding
Data Partitioning Strategy
Horizontal Sharding
- Partition Key: User ID (hash-based)
- Rationale:
- Even distribution of email traffic across shards
- Reduces hotspots and improves parallel processing capabilities
- Simple to implement with consistent hashing algorithm
- Supports predictable scaling as user base grows
Range Partitioning for Metrics
- Partition Key: Timestamp (monthly ranges)
- Rationale:
- Time-based analytics queries are common
- Efficient for archiving older data (e.g., 30-day retention policy)
- Simplifies backup and maintenance operations
Data Replication Strategy
Primary-Replica Architecture
- Master: PostgreSQL primary instance
- Replicas: Read replicas for analytics and reporting workloads
- Replication Type: Streaming replication with async commit
- Failover: Automated failover using Patroni or similar tooling
Cross-service Data Ownership
- No Shared Databases: Each service owns its data store
- Enforcement Strategy:
- Database access control at application level (RBAC)
- Service-to-service communication through well-defined APIs
- Audit logging for any cross-service database access attempts
CQRS Pattern Application
Email Service
- Read Side: PostgreSQL (primary)
- Write Side: PostgreSQL with event sourcing for delivery tracking
- Use Case: Complex email lifecycle management (draft, send, retry, bounce handling)
Metrics Service
- Read Side: TimescaleDB (for analytics)
- Write Side: In-memory buffer with periodic batch writes to TimescaleDB
- Use Case: Real-time analytics and reporting
Event Sourcing Consideration
Selected Approach:
- Email Delivery Events: Event store using Kafka
- Rationale:
- Immutable audit trail for email delivery lifecycle
- Enables complex event-driven workflows (retry logic, analytics)
- Supports replay for debugging and compliance reporting
- Better scalability than traditional database logging
Storage Tiering Strategy
Hot Tier (1-30 days)
- Storage: SSD-backed PostgreSQL and Redis
- Access Pattern: High-frequency read/write operations
- Cost: Highest but necessary for performance
Warm Tier (30-90 days)
- Storage: HDD-backed PostgreSQL with read replicas
- Access Pattern: Periodic analytics and historical queries
- Cost: Moderate, optimized for cost vs. performance
Cold Tier (90+ days)
- Storage: Object storage (S3/GCS) with lifecycle policies
- Access Pattern: Archival and compliance retrieval
- Cost: Lowest, optimized for long-term storage
Backup and Restore Strategy
Backup Frequency:
- Full Backups: Daily (incremental backups every 4 hours)
- Incremental Backups: Every 4 hours
- Point-in-Time Recovery: Enabled with WAL archiving
RTO/RPO Targets:
- RTO: 15 minutes (full restore from backup)
- RPO: 5 minutes (maximum data loss in case of failure)
Backup Storage:
- Primary: Cloud-native backup storage (AWS S3, GCP Cloud Storage)
- Secondary: Cross-region replication for disaster recovery
Restore Process:
- Automated Recovery: Failover to replica with automated promotion
- Manual Recovery: Full restore from backup with validation checks
- Testing: Monthly restore drills to validate backup integrity
6. Caching Architecture
Caching Layers and Strategy
The caching architecture follows a multi-tier approach to optimize performance and reduce database load:
graph LR
A[Client] --> B[CDN]
B --> C[API Gateway]
C --> D[Application Layer]
D --> E[In-Memory Cache (L1)]
E --> F[Redis Cluster (L2)]
F --> G[Database]
Layered Cache Strategy:
- L1 Cache: In-memory cache within application instances (e.g., Guava/Caffeine)
- L2 Cache: Distributed Redis cluster for cross-service sharing
- CDN Layer: For static email assets and templates (if applicable)
- Database Level: Read replicas and query caching (not part of application cache)
Cache In-Memory vs. Distributed Strategy
L1 Cache (Application Level):
- Implementation: Guava Cache or Caffeine in each application instance
- Size: 100-500MB per instance (configurable based on memory constraints)
- Eviction Policy: LRU with time-based expiration (5-10 minutes)
- Use Case: Frequently accessed email templates, user preferences, and metadata
L2 Cache (Redis Cluster):
- Implementation: Redis 7.x with cluster mode
- Size: 2-4GB per Redis node (configurable)
- Eviction Policy: All keys with TTL, LRU eviction policy
- Use Case: Shared caches across services (user profiles, email content, delivery status)
- Replication: 3x replica for high availability
Cache Consistency and Invalidation Strategy
Cache Invalidation Patterns:
- Write-through: Update cache on write operations (user profile updates)
- Cache-Aside: Load from DB and populate cache on read misses (email templates)
- Write-Behind: Batch updates to cache and DB asynchronously
Consistency Mechanism:
- Cache invalidation via pub/sub when data changes (e.g., user preferences updated)
- TTL-based expiration with background refresh for hot keys
- Cache warming strategy for critical templates and user data
Cache Warming Strategy
Cold Start Handling:
- Pre-warm cache during service startup with frequently accessed templates
- Warm cache on service health check and periodic background jobs
- Template pre-loading for high-volume email types (transactional, marketing)
- Cache warming via scheduled jobs with priority queueing
Cache Hit Rate Assumptions:
- L1 cache hit rate: 70-85% (based on application instance reuse)
- L2 cache hit rate: 90-95% (cross-service sharing)
- Overall effective cache hit rate: ~92-95%
- Resulting DB QPS reduction: 80-90% (assuming 10x read ratio)
Cache Size and Performance Trade-offs
Memory Allocation:
- Per-service instance: 500MB L1 cache (200k entries max)
- Redis cluster: 4GB per node (500k entries max)
- Memory allocation based on hot key distribution analysis
- Eviction policy tuned for 95% hit rate with minimal cache misses
Performance Impact:
- L1 cache reduces latency by 60-80% for frequently accessed data
- L2 cache reduces database load by 85-90%
- Cache warming adds 10-20ms startup overhead but reduces cold start latency by 50-70%
- Memory usage increases by ~20-30% of total application memory
Cache Failure Handling
Graceful Degradation:
- Fail-open strategy for non-critical data (user preferences, templates)
- Fail-closed for critical delivery status and user identity
- Fallback to database reads with circuit breaker pattern
- Cache warming retry mechanism for critical templates
Cache Eviction Strategy:
- Time-based TTL with sliding window (5-10 minutes)
- Size-based eviction for L1 cache (max 200k entries)
- Priority-based eviction for L2 cache (user session vs. template data)
- Background cleanup jobs to prevent memory leaks
This caching architecture provides a balance between performance optimization, cost efficiency, and system reliability while maintaining data consistency across services.
7. Messaging & Event Streaming Architecture
Message Broker Selection
For email delivery service, we'll use Apache Kafka as the primary message broker due to:
- High throughput requirements: Email service needs to handle millions of emails daily with low latency
- Durability guarantees: Kafka's persistence model ensures no email loss during delivery failures
- Scalable consumer model: Support for multiple consumers (delivery workers, analytics, monitoring)
- Stream processing capabilities: Enables real-time analytics and delivery tracking
- Production maturity: Proven at scale in high-throughput systems
Event Schema Registry and Versioning
We'll implement Confluent Schema Registry for:
- Schema evolution management: Handle backward/forward compatibility
- Type safety: Prevent malformed email events from being published
- Version control: Track event schema changes with rollback capability
- Validation at publish time: Ensure all email events conform to expected structure
Topic Partitioning and Consumer Group Design
Email Delivery Topics:
email-delivery-queue(100 partitions) - primary delivery queueemail-delivery-status(50 partitions) - delivery status updatesemail-analytics(25 partitions) - engagement metricsemail-failures(10 partitions) - retry and failure handling
Consumer Groups:
delivery-workers(50 consumer instances) - primary email deliveryanalytics-consumers(10 consumer instances) - metrics processingfailure-handlers(5 consumer instances) - retry and dead letter queue
Event Ordering Guarantees
- Per-user ordering: Within
email-delivery-queue, events are partitioned by user ID to maintain delivery order per recipient - Global ordering: Not required for most use cases, but can be achieved with single partition if needed
- Partition key strategy: User ID hash as partition key to ensure consistent routing
Exactly-once vs. At-least-once Processing Trade-offs
Decision: At-least-once processing with idempotent consumers
Justification:
- Email delivery is idempotent: Re-sending the same email to a user doesn't cause harm
- Simpler implementation: Avoids complex state management for exactly-once semantics
- Better fault tolerance: If consumer crashes, reprocessing is safe and simple
- Performance: Lower overhead compared to exactly-once mechanisms
Event Replay and Reprocessing Strategy
Replay capability:
- Kafka's retention policy (7 days) enables event replay for debugging and reprocessing
- Dedicated
email-replaytopic for historical data processing - API endpoint to trigger reprocessing of specific user/email batches
Reprocessing workflow:
- Identify failed or missing deliveries
- Replay relevant events from Kafka
- Update delivery status in database
- Notify monitoring systems of reprocessing
Dead Letter Queue and Poison Pill Handling
DLQ Strategy:
email-delivery-failurestopic for failed deliveries- Max retry count of 3 before routing to DLQ
- Failed messages with metadata (user ID, email template, timestamp) for debugging
Poison pill handling:
- Messages that fail 3+ times are moved to DLQ with error context
- Dedicated monitoring dashboard for DLQ messages
- Manual intervention workflow for persistent failures (e.g., malformed addresses)
- Auto-escalation to human operators after 24 hours in DLQ
Message Format and Serialization
Event format:
{
"eventId": "uuid",
"eventType": "email.deliver",
"timestamp": "2023-01-01T12:00:00Z",
"userId": "user-123",
"emailId": "email-456",
"templateId": "welcome-email",
"recipient": {
"email": "user@example.com",
"name": "John Doe"
},
"payload": {},
"metadata": {
"priority": "normal",
"retryCount": 0,
"source": "web-app"
}
}
Serialization: JSON with schema validation, compressed for efficiency
Cross-service Event Integration
Integration points:
user-service→email-delivery(user creation, email updates)analytics-service→email-analytics(engagement tracking)notification-service→email-delivery(urgent notifications)
Event-driven architecture benefits:
- Loose coupling between services
- Async processing enables better scalability
- Fault isolation (failure in one service doesn't block others)
- Real-time processing capabilities for engagement tracking
Event Processing Pipeline
Delivery pipeline:
- Email creation →
email-delivery-queue(publisher) - Delivery workers consume from queue → process and send via SMTP
- Status updates →
email-delivery-status(publisher) - Analytics →
email-analytics(publisher)
Monitoring pipeline:
- Delivery failures →
email-failures(publisher) - Retry logic →
email-delivery-queue(re-publish with delay) - Alerting → external monitoring systems
Performance and Capacity Considerations
Partition sizing:
- 100 partitions for main queue to support 1M+ concurrent users
- 50 partitions for status updates to handle high-volume delivery tracking
- 25 partitions for analytics to support real-time metrics
Consumer scaling:
- Auto-scaling based on queue depth and processing lag
- Horizontal scaling of delivery workers to handle peak loads
- Dynamic partition assignment for optimal load distribution
This messaging architecture provides the foundation for a highly available, scalable email delivery service with robust failure handling and real-time processing capabilities.
8. Reliability Engineering
Failure Mode Analysis
Single Points of Failure:
- Email delivery service primary database (PostgreSQL) - single point for all email state and queue management
- Message broker (Apache Kafka) - single point for all email event processing and retries
- API Gateway - single point for all external request routing and authentication
- Email sending service (SMTP relay) - single point for actual email delivery to external providers
- Cache layer (Redis) - single point for all caching of email metadata and templates
Critical Failure Scenarios:
- Database connection pool exhaustion causing service unavailability
- Kafka broker outage causing email queue backlog and processing delays
- External SMTP provider downtime causing email delivery failures
- Cache cluster failure causing high DB load and degraded performance
- API Gateway rate limiting misconfiguration causing legitimate traffic throttling
Fault Tolerance Patterns
Circuit Breaker Pattern:
- Implemented at SMTP relay service to prevent cascading failures when external providers are unavailable
- Circuit breaker monitors failure rate and automatically trips after 5 consecutive failures within 10 seconds
- After trip, circuit remains open for 30 seconds before allowing test requests
Bulkhead Pattern:
- Database connection pools isolated per service (delivery, queue management, templates)
- Separate thread pools for email sending vs. metadata operations
- Rate limiting per email provider to prevent overloading individual SMTP endpoints
Timeout and Retry Patterns:
- 5-second timeout for SMTP delivery requests with exponential backoff (1s, 2s, 4s, 8s)
- Maximum 3 retries for transient failures (network timeouts, rate limits)
- Retry logic with jitter to prevent thundering herd on retries
Multi-Region / Multi-AZ Strategy
Active-Active Architecture:
- Primary region (us-east-1) handles 80% of traffic, secondary region (us-west-2) handles 20%
- Cross-region replication for critical data using Kafka topic replication
- DNS failover with 30-second TTL to ensure rapid traffic routing to healthy region
Cross-Region Email Queue:
- Kafka clusters in both regions with cross-region replication
- Email queue state synchronized via distributed consensus (Raft-based)
- Regional delivery services can process from local queue while maintaining global consistency
Chaos Engineering Strategy
GameDays:
- Weekly 2-hour GameDays focused on email delivery service resilience
- Simulate database outages, Kafka broker failures, SMTP provider unavailability
- Test circuit breaker behavior and retry logic under load
Steady-State Hypotheses:
- Email delivery service remains available with 99.9% uptime during simulated failures
- Queue processing continues with minimal latency degradation when individual components fail
- User email delivery completes within 5 seconds under normal conditions
Disaster Recovery Plan
RTO/RPO Targets:
- RTO: 5 minutes for primary service availability (including failover)
- RPO: 1 minute for email queue and state consistency
- Data backup retention: 30 days with point-in-time recovery capability
Recovery Procedures:
- Failover to secondary region within 2 minutes of primary region outage
- Restore Kafka topic state from last backup within 15 minutes
- Rehydrate Redis cache from last snapshot within 30 minutes
- Resume email delivery after database recovery within 1 hour
Runbook Design for Top-5 Failure Scenarios
1. SMTP Provider Outage
- Alert: Email delivery latency > 30 seconds
- Action: Trip circuit breaker, send alert to operations team
- Recovery: Route emails through backup SMTP providers or queue for retry
2. Database Connection Pool Exhaustion
- Alert: DB connection pool usage > 90%
- Action: Trigger auto-scaling, implement connection pooling limits
- Recovery: Restart database connections after pool reset
3. Kafka Broker Failure
- Alert: Kafka consumer lag > 5 minutes
- Action: Failover to secondary Kafka cluster, reconfigure consumers
- Recovery: Restore topic replication and resume processing
4. Cache Cluster Unavailability
- Alert: Cache hit rate drops below 20%
- Action: Disable cache layer, route all requests to database
- Recovery: Restart Redis cluster and warm cache with hot keys
5. API Gateway Rate Limiting Misconfiguration
- Alert: 429 responses > 1% of total requests
- Action: Adjust rate limit thresholds, send alert to SRE team
- Recovery: Revert configuration changes and re-enable normal rate limits
9. Observability Architecture
Logging Stack
The system will implement a structured logging approach using JSON format for all service logs to enable efficient parsing and querying. Logs will be collected through a centralized logging system like Loki (for open-source) or CloudWatch (for AWS) with support for log retention policies. Each service will emit logs at INFO level by default, with DEBUG and ERROR levels for troubleshooting. Log aggregation will be handled via a centralized logging pipeline that forwards logs to a durable storage backend for long-term retention and analysis.
Distributed Tracing
Distributed tracing will be implemented using OpenTelemetry (OTel) with Jaeger as the tracing backend for distributed request flow visualization. Each microservice will instrument its own traces with span IDs and correlation context propagated through service boundaries. Critical paths such as email processing, delivery, and failure handling will be instrumented with detailed span information to enable root cause analysis. Tracing data will be sampled at 1% for production workloads with full trace capture for error cases and high-volume user paths.
Metrics Stack
Metrics collection will be implemented using Prometheus as the primary time-series database, with Grafana for dashboard visualization. Key metrics include:
- Email delivery success/failure rates
- Processing latency (p50/p95/p99)
- Queue depths and processing rates
- Retry counts and backoff behavior
- Cache hit/miss ratios
- Database query latencies
Metrics will be collected at 15-second intervals with a retention policy of 90 days for operational insights and 30 days for historical trend analysis.
Alerting Strategy
The alerting system will use a multi-tiered severity model:
- P0 (Critical): Email delivery failures > 5% of volume, system downtime, cache unavailability
- P1 (High): Latency above p99 threshold, queue depth exceeding thresholds, high retry rates
- P2 (Medium): Cache miss rates > 10%, database connection pool exhaustion
Alerts will be routed through PagerDuty with escalation policies and on-call rotation management. Alert thresholds will be dynamically adjusted based on historical baselines and business hours.
SLI/SLO Definition
SLIs will be defined as:
- Delivery Success Rate: (Delivered Emails / Total Sent Emails) * 100%
- Delivery Latency: p50/p95/p99 delivery time in seconds
- Availability: System uptime percentage
SLOs will target:
- 99.9% delivery success rate (100 emails = 1 failure max)
- 95th percentile delivery latency under 30 seconds
- 99.9% system availability (1.44 minute downtime max/month)
Error budget will be tracked with a dashboard showing remaining error budget and burn rate for each service.
Capacity Planning and Load Forecasting
Capacity planning will be driven by historical email volume trends, user growth projections, and seasonal patterns. Load forecasting models will predict peak delivery hours and resource requirements with 95% confidence intervals. The system will automatically scale based on forecasted load patterns and real-time metrics, with capacity alerts triggered when projected utilization exceeds 80% thresholds.
The observability stack will support real-time incident response, historical trend analysis, and proactive capacity management to ensure optimal email delivery performance at scale.
10. API Gateway & Edge Layer
API Gateway Selection
For an email delivery service, I recommend AWS API Gateway as the primary API gateway solution. This decision is based on:
- Managed service benefits: Reduces operational overhead of maintaining custom gateways
- Native AWS integration: Seamless integration with Lambda, ECS, and other AWS services
- Built-in rate limiting and throttling: Essential for preventing abuse and ensuring fair usage
- Authentication integration: Native support for Cognito, IAM, and custom auth providers
- Request/response transformation: Built-in mapping templates for payload manipulation
Alternative considerations include Kong (for on-premises flexibility) or custom Nginx-based solutions, but these introduce operational complexity and maintenance burden.
Request Routing Strategy
The API gateway will implement a multi-tenant routing strategy with:
- Service-based routing:
/api/v1/emails→ Email Service,/api/v1/templates→ Template Service - Version-aware routing:
/api/v1/emails/sendvs/api/v2/emails/sendfor API evolution - Regional routing: Route requests to the nearest regional service endpoint for low latency
Authentication and Authorization
At the gateway layer:
- OAuth2/OIDC support: Integration with AWS Cognito or custom IdP for user authentication
- API key validation: For partner/service-to-service authentication
- RBAC enforcement: Role-based access control for different email operation scopes (send, read, manage templates)
- Token validation: JWT verification with proper audience and issuer claims
Rate Limiting and Throttling Design
Global rate limiting:
- 1000 requests/minute per user for send operations
- 5000 requests/minute for read/list operations
- 10000 requests/minute for template operations
Per-client limits:
- Partner API keys with 50,000 requests/hour limit
- Per-user limits for free tier (100 emails/day)
- Burst capacity handling with token bucket algorithm
Request Transformation and Protocol Translation
The gateway will handle:
- Content negotiation: Accept header handling for different response formats (JSON, XML)
- Protocol translation: HTTP to gRPC for internal microservices
- Payload transformation: Schema validation and conversion between formats (e.g., JSON to internal protobuf)
- Header manipulation: Adding trace IDs, security headers, and service-specific metadata
BFF (Backend for Frontend) Design
For the web dashboard, a BFF pattern will be implemented:
- User-specific view aggregation: Combine email status, templates, and analytics into single dashboard response
- Client-side caching strategy: Cache policy enforcement for reducing backend load
- Security boundary: Shield internal services from direct client access
- Optimized payload structure: Reduce bandwidth usage for web clients
The BFF will handle:
- Email list pagination with pre-aggregated stats
- Template preview rendering
- User preferences and settings consolidation
- Real-time status updates via WebSocket connections
This approach ensures optimal client experience while maintaining service security and scalability. The gateway acts as a security perimeter, traffic coordinator, and protocol adapter that enables the underlying microservices to focus on business logic rather than cross-cutting concerns like authentication, rate limiting, and payload transformation.
11. Authentication & Authorization Architecture
Identity Provider Integration
For email delivery service, we'll integrate with AWS Cognito as the primary identity provider. This choice provides:
- Native integration with AWS services and infrastructure
- Support for federated identities (Google, Facebook, Microsoft)
- Built-in user pools and identity federation capabilities
- Seamless integration with AWS WAF for security controls
- Cost-effective for moderate-scale operations
OAuth2/OIDC Flow Design
sequenceDiagram
participant Client
participant API_Gateway
participant Auth_Service
participant Cognito
participant User
Client->>API_Gateway: Request protected endpoint
API_Gateway->>Auth_Service: Forward request with token
Auth_Service->>Cognito: Validate JWT token
Cognito-->>Auth_Service: Return token validation result
Auth_Service->>Client: Forward request or reject with 401
The system implements a standard OAuth2 Authorization Code flow with PKCE for public clients, supporting both web and mobile applications. The authorization server handles token issuance, validation, and revocation.
Service-to-Service Authentication
For inter-service communication, we implement mTLS with SPIFFE/SPIRE for secure service identity management:
- Each service runs with a unique SPIFFE ID
- mTLS handshake validates service identities using X.509 certificates
- Certificate rotation handled through SPIRE's automatic renewal
- Service-to-service communication is encrypted and authenticated at the transport layer
RBAC vs ABAC Model
We implement a hybrid approach:
- Role-Based Access Control (RBAC) for administrative and operational access
- Admin roles: Full system access, configuration changes
- User roles: Email sending, read-only access to reports
- Attribute-Based Access Control (ABAC) for granular policy enforcement:
- Email domain-based access control
- Rate limiting based on user tier and subscription level
- Content filtering permissions based on sender reputation
Token Revocation Strategy
We implement a multi-layered token revocation approach:
- Short-lived JWT tokens (15-30 minutes) with refresh token rotation
- Blacklist-based revocation for immediate token invalidation (e.g., user logout, compromised tokens)
- Refresh token rotation - each refresh generates a new refresh token with reduced lifetime
- Session management - track active sessions for immediate revocation capability
Token Management Architecture
User Authentication Flow:
1. User authenticates via Cognito
2. Cognito issues JWT with claims (sub, iss, exp, roles)
3. API Gateway validates token signature and claims
4. Auth Service caches validated tokens with TTL
5. Token refresh handled via refresh token rotation
Security Considerations
- All tokens are encrypted at rest and in transit using TLS 1.3+
- Token validation includes audience, issuer, and expiration checks
- Refresh tokens are stored in secure HTTP-only cookies with SameSite attributes
- Session timeout policies enforced at the application layer
- Regular token rotation and cleanup of expired sessions
Compliance Considerations
The authentication system supports:
- OAuth2.0 compliance for third-party integrations
- JWT token standards (RFC 7519) with proper claim structure
- Audit logging of authentication events for compliance reporting
- Support for SSO integration with enterprise identity providers
- GDPR-compliant user data handling and consent management
Scalability Implications
- Authentication service is stateless with minimal session storage
- Token validation is optimized through caching and pre-computed claims
- Load balancing across authentication instances with shared secrets store
- Horizontal scaling capability for high-concurrency authentication scenarios
12. Search Architecture
Search Use Cases and Requirements
Email delivery services typically don't require complex search capabilities as their primary function is email delivery and routing. However, if the system includes email search functionality (e.g., user searching through their email inbox), we would implement a search architecture to support this capability.
Search Indexing Pipeline
The search indexing pipeline follows a publish-subscribe model:
- Source: Email events (new email received, email updated, email deleted)
- Transform: Extract relevant fields (subject, sender, recipient, body content, timestamp, labels)
- Index: Store searchable document in search engine with metadata and content
Index Schema Design
Search indexes would be designed with the following key fields:
email_id(primary key)user_id(for user-level search isolation)subject(full-text searchable)sender(email address, name)recipients(array of email addresses)body_content(full-text searchable)timestamp(for time-range queries)labels(folder/label classification)is_read(read/unread status)priority(high/normal/low)
Search Query Patterns
Primary query patterns include:
- Subject and body text search (full-text)
- Sender/recipient filtering
- Date range filtering
- Label/folder filtering
- Read/unread status filtering
Real-time vs. Near-real-time Indexing Trade-offs
For email search, we would implement near-real-time indexing (1-5 minute delay) to balance:
- Latency: Users expect search results to be available within minutes of email receipt
- Resource cost: Real-time indexing would require significant compute resources for each email
- Consistency: Near-real-time provides acceptable consistency for most use cases
Relevance Tuning Strategy
Relevance ranking would consider:
- Text matching weight: Subject and body content matching
- Temporal relevance: Recent emails receive higher weights
- Sender importance: User-configured trusted senders get boosted scores
- Label relevance: Inbox emails receive higher ranking than spam/folder emails
Search Scaling Design
Search service would use sharding strategy:
- Shards per user: Each user's email set stored in dedicated shards
- Replication factor: 3x replication for fault tolerance
- Index partitioning: Based on user_id hash ranges
- Query routing: Service routes queries to appropriate shard based on user_id
Search Engine Selection
For email search, we would use Elasticsearch or OpenSearch due to:
- Excellent full-text search capabilities
- Rich query DSL support for complex filtering
- Native support for multi-field search
- Strong community and enterprise support
- Easy integration with existing observability stack
Search Performance Targets
- Query latency: p50 < 100ms, p95 < 500ms, p99 < 2s
- Indexing throughput: 10,000 emails/minute for peak load
- Search availability: 99.9% uptime with automatic failover
Search Service Integration
Search service would be integrated as a separate microservice that:
- Listens to email events via message queue
- Maintains search index in real-time or near-real-time
- Provides REST API for search queries to frontend services
- Supports pagination and filtering capabilities
Search Result Presentation
Search results would be returned with:
- Email metadata (subject, sender, timestamp)
- Snippet preview of matching content
- Relevance score for result ranking
- Thread information for email conversations
13. Scalability Deep Dive
Bottleneck Identification
Email Processing Pipeline:
- Ingestion Layer: Peak QPS of ~80,000 (10x average) for 8M DAU
- Processing Layer: Database QPS of ~8,000 (assuming 10% cache hit rate)
- Delivery Layer: SMTP relay throughput limited to ~5,000 emails/sec per server
- Storage Layer: 2GB/user/year (assuming 500 emails/user with 4KB avg size)
Bottleneck Analysis:
- Database: Read-heavy workload with 80% reads, peak QPS of ~8,000
- SMTP Delivery: Rate-limited by external providers (5k emails/sec)
- Storage: 20TB/year growth with 5x write amplification from indexing
- Caching: Cache warming under high load (cold start penalty of 200ms)
Horizontal vs. Vertical Scaling Strategy
Vertical Scaling:
- Database: Vertical scaling to 64-core, 256GB RAM instances for read-heavy workloads
- Application Servers: 32-core, 128GB RAM for high-concurrency processing
- SMTP Relays: Dedicated high-throughput servers (5k emails/sec each)
Horizontal Scaling:
- Email Processing: Horizontal sharding by user ID (hash-based partitioning)
- Delivery Service: Multi-zone delivery clusters with auto-scaling
- Storage: Horizontal partitioning across multiple storage nodes
Database Scaling Path
Phase 1 (0-5M users):
- Single PostgreSQL instance with read replicas (3x)
- 100GB storage capacity
Phase 2 (5M-50M users):
- Horizontal sharding by user ID hash (16 shards)
- Read replicas per shard (3x each)
- Connection pooling with 500 concurrent connections per shard
Phase 3 (50M+ users):
- Distributed database (CockroachDB or Spanner)
- Multi-region replication with 20% read latency increase
- Cross-shard joins handled via materialized views
Stateless vs. Stateful Service Design
Stateless Services:
- Ingestion API: Stateless, handles email queueing and validation
- Processing Engine: Stateless, processes emails in batches
- Delivery Coordinator: Stateless, manages delivery routing and retry logic
Stateful Services:
- Email Storage: Stateful, maintains email metadata and content
- Delivery Logs: Stateful, stores delivery status and retry history
- User Preferences: Stateful, maintains user-specific delivery settings
State Management Strategy:
- Session affinity for delivery logs (user-based hashing)
- Distributed state via Redis cluster with 3x replication
- State synchronization via event streaming (Kafka)
Session Affinity and Implications
User-Based Session Affinity:
- Implementation: Hash-based consistent hashing of user IDs
- Impact: 10% cache miss rate increase due to sharding
- Mitigation: Cross-shard caching with Redis cluster
Delivery Session Management:
- Stateful Sessions: 100ms per session lookup overhead
- Caching Strategy: L2 cache with 30s TTL for user delivery preferences
- Fallback: Read-through caching with database fallback
Scalability Implications:
- Sharding Key: User ID hash with 16 shards for balanced distribution
- Partitioning Strategy: Range-based partitioning for user preference queries
- Cross-Shard Operations: Event-driven coordination via Kafka topics
Performance Bottlenecks and Mitigation
Database Read Bottleneck:
- Impact: 30% of requests blocked by database contention
- Mitigation:
- Read replicas (3x) with query caching
- Materialized views for common report queries
- Connection pooling with 500 concurrent connections
Delivery Rate Limiting:
- Impact: 20% of emails delayed due to external provider limits
- Mitigation:
- Multi-provider delivery with automatic failover
- Rate-limiting queue with exponential backoff
- Delivery scheduling with batch processing
Storage Growth Bottleneck:
- Impact: 40% annual storage growth requiring infrastructure upgrades
- Mitigation:
- Tiered storage with hot/warm/cold access patterns
- Compression strategies (20% space reduction)
- Archiving policy for emails older than 1 year
Auto-Scaling Triggers and Thresholds
CPU Utilization:
- Threshold: >70% CPU for 5 minutes
- Trigger: Auto-scale up by 25% of current capacity
- Cooldown: 10 minutes between scaling actions
Memory Usage:
- Threshold: >85% memory usage
- Trigger: Scale up by 10% of current capacity
- Cooldown: 5 minutes between actions
Queue Depth:
- Threshold: >5,000 pending emails
- Trigger: Scale up by 50% of current capacity
- Cooldown: 15 minutes between actions
Delivery Latency:
- Threshold: >200ms average delivery time
- Trigger: Scale up by 15% of current capacity
- Cooldown: 5 minutes between actions
Load Distribution Strategy
Traffic Sharding:
- User ID Hashing: Consistent hashing with 16 shards
- Load Balancing: Round-robin with weighted distribution
- Health Checks: 5-second intervals with 3x retry logic
Cross-Service Load Balancing:
- API Gateway: Distributes requests across 8 processing nodes
- Database: Read replicas with weighted load distribution
- Delivery Service: Multi-zone clusters with auto-failover
Failure Recovery:
- Graceful Degradation: Service degradation with 50% capacity
- Failover Mechanism: Automatic re-routing to healthy nodes
- Recovery Time: <30 seconds for service recovery
Resource Utilization Optimization
CPU Efficiency:
- Optimization: 25% CPU reduction through batch processing
- Parallelism: 8 concurrent threads per email processing task
- Resource Pooling: Shared connection pools for database and SMTP
Memory Optimization:
- Object Pooling: 30% memory reduction through object reuse
- Compression: 20% memory savings with gzip compression
- Caching Strategy: LRU eviction policy with 10GB cache limit
Network Utilization:
- Bandwidth: 50% reduction in network traffic through compression
- Latency: <50ms average for inter-service communication
- Connection Management: Keep-alive connections with 30-second timeout
Capacity Planning Projections
Peak Load Projections:
- QPS: 80,000 peak QPS (10x average)
- Storage: 20TB/year growth with 5x write amplification
- Delivery: 10,000 emails/sec peak delivery rate
Scaling Factors:
- User Growth: 5x growth over 2 years (from 8M to 40M users)
- Throughput: 3x increase in processing capacity required
- Storage: 10x storage capacity expansion needed
Infrastructure Requirements:
- Database: 200 database instances (16 shards × 12.5 nodes)
- Processing: 400 application servers (25% horizontal scaling)
- Delivery: 200 SMTP relay servers (5k emails/sec each)
14. Infrastructure & Deployment Architecture
Cloud Provider and Region Selection
For a global email delivery service, we'll target AWS as the primary cloud provider due to its mature ecosystem, extensive global footprint, and robust networking capabilities. The service will be deployed across multiple regions to ensure low latency and high availability:
- Primary Region: us-east-1 (US East) - for global traffic routing and primary operations
- Secondary Region: eu-west-1 (Europe) - for EU-based users and disaster recovery
- Tertiary Region: ap-southeast-1 (Asia Pacific) - for Asia-Pacific users
This multi-region strategy enables us to provide sub-500ms latency to 95% of users while maintaining fault tolerance.
Kubernetes Cluster Design
We'll deploy a multi-tenant Kubernetes cluster architecture:
- Control Plane: Managed AWS EKS clusters with 3 control plane nodes across availability zones for high availability
- Node Pools:
- Standard Pool: General-purpose workloads (compute-optimized)
- High-Memory Pool: For email processing and content analysis services
- GPU Pool: For AI-based spam detection and content filtering (if required)
- Namespaces:
email-service-prod- Production servicesemail-service-staging- Staging and testing environmentsemail-service-internal- Internal services and tooling
Container Image Strategy
All container images will follow a multi-stage build approach:
- Base Images: Alpine Linux or Debian Slim for minimal footprint
- Build Process:
- Stage 1: Build dependencies and compile application code
- Stage 2: Copy only necessary runtime components to final image
- Registry: AWS ECR with image scanning for vulnerabilities and compliance
Deployment Strategy
We'll implement a hybrid deployment approach:
- Primary Strategy: Blue-Green deployments with traffic shifting via AWS Application Load Balancer
- Canary Strategy: For new features, deploy to 5% of traffic with automatic rollback if errors exceed threshold
- Rollback Triggers:
- Error rate > 5% over 5 minutes
- Latency p99 > 2s for 10 minutes
- Memory/CPU spikes exceeding thresholds
Auto-Scaling Design
Horizontal and vertical auto-scaling will be implemented:
- HPA (Horizontal Pod Autoscaler):
- Target CPU utilization: 70%
- Target Memory utilization: 80%
- VPA (Vertical Pod Autoscaler):
- For memory and CPU resource recommendations based on historical usage
- KEDA (Kubernetes Event Driven Autoscaler):
- For email queue consumers and processing services
- Triggers based on message queue depth and processing backlog
Infrastructure as Code Approach
Infrastructure will be managed using Terraform with the following structure:
- Modules:
eks-cluster- EKS cluster and node groupsvpc-networking- VPC, subnets, security groupsiam-policies- IAM roles and policies for servicesmonitoring- CloudWatch, Prometheus, Grafana integration
- State Management:
- Remote state using S3 backend with DynamoDB locking for consistency
- Version Control:
- GitOps approach using ArgoCD for declarative deployment management
- Terraform version pinning to ensure reproducible deployments
Resource Management and Quotas
- Resource Quotas:
- CPU: 2000m (2 cores) per namespace
- Memory: 4Gi per namespace
- Limit Ranges:
- Default CPU limit: 500m per pod
- Default Memory limit: 1Gi per pod
- Pod Disruption Budgets:
- Minimum available pods: 80% for critical services
- Max unavailable pods: 20% for non-critical services
Multi-Tenant Considerations
- Isolation:
- Namespace-based isolation for different customer tenants
- Resource quotas to prevent cross-tenant resource exhaustion
- Network Isolation:
- VPC per tenant with dedicated subnets and security groups
- Service mesh integration for cross-tenant communication control
Disaster Recovery Considerations
- Cross-Region Replication:
- Email queue and state replication across regions
- Database read replicas in secondary regions
- Backup Strategy:
- EBS snapshots for persistent volumes
- S3 backups of configuration and metadata
- Recovery Time Objectives:
- RTO: < 15 minutes for primary services
- RPO: < 5 minutes for critical data
Observability and Monitoring Integration
- Cluster Monitoring:
- Prometheus metrics collection from all pods
- CloudWatch integration for AWS-native monitoring
- Logging:
- Centralized logging using Fluentd/FluentBit to CloudWatch
- Structured JSON logging for easy parsing and filtering
This infrastructure design provides a scalable, resilient foundation that supports the email delivery service's global reach and high availability requirements while maintaining operational simplicity through declarative infrastructure management.
15. Security Architecture
VPC Design and Network Segmentation
The system operates within a multi-AZ VPC with public and private subnets to enforce network segmentation. Public subnets host load balancers and API gateways, while private subnets contain application services, databases, and message brokers. All inter-service communication occurs within the private network using internal VPC endpoints to minimize exposure to external threats. Cross-account VPC peering is implemented for multi-region deployments with strict route table controls.
Zero-Trust Network Model
All network traffic is subject to zero-trust principles, requiring explicit authorization for every request regardless of origin. Services authenticate and authorize each other using mTLS with certificate-based authentication, enforced through service mesh (Istio) for consistent policy enforcement. Network policies are implemented using Kubernetes NetworkPolicies to restrict pod-to-pod communication within namespaces.
TLS Termination Strategy
TLS termination occurs at the API gateway layer with strict cipher suite enforcement (TLS 1.3+ only) and certificate rotation every 90 days. All internal service-to-service communication uses mTLS with mutual certificate validation to prevent man-in-the-middle attacks. Certificate management is handled through AWS ACM Private CA for internal certificates and Let's Encrypt for public endpoints.
DDoS Protection Strategy
DDoS protection is implemented at multiple layers:
- AWS Shield Advanced for Layer 3/4 protection with automatic mitigation
- Rate limiting at API Gateway to prevent abuse of email sending endpoints
- CloudFront integration for DDoS protection at the edge layer
- IP reputation filtering to block known malicious sources
Secrets Management Architecture
Secrets are managed through AWS Secrets Manager with automatic rotation for credentials and API keys. Service accounts use IAM roles with least-privilege access instead of hard-coded secrets. Secrets are injected into containers at runtime via Kubernetes secrets or AWS Secrets Manager integration, with automatic refresh on rotation events.
Vulnerability Scanning in CI/CD
Vulnerability scanning is integrated into the CI/CD pipeline using Trivy for container image scanning and Snyk for dependency analysis. Security checks are enforced as mandatory gates in the build process, blocking deployments with critical or high severity vulnerabilities. Container images are built from minimal base images with security patches applied.
WAF Rules for Critical Endpoints
AWS WAF is deployed to protect critical email delivery endpoints with custom rules:
- Rate-based rules to prevent spamming and abuse
- IP address blocklists for known malicious sources
- SQL injection and XSS protection rules
- Size constraints to prevent oversized payloads
- Custom rule sets for email-specific validation (RFC compliance, attachment size limits)
Data Protection and Encryption
All data at rest is encrypted using AWS KMS with customer-managed keys. Email content and metadata are encrypted before storage, with key rotation policies enforced quarterly. Data in transit is protected using TLS 1.3+ for all external communications and mTLS for internal service communication.
Compliance and Audit
The system supports SOC2 Type II compliance with automated audit logging for all email delivery operations. Audit trails capture email send events, delivery status changes, and system configuration modifications. Access logs are aggregated to CloudWatch with retention policies ensuring 7-year compliance for financial audit requirements.
16. Deployment & Release Strategy
Deployment Strategy
The email delivery service will utilize a blue-green deployment strategy for production releases to ensure zero-downtime deployments and seamless rollback capability. This approach involves maintaining two identical production environments where only one is active at any time. When deploying a new version, traffic is shifted from the old environment to the new one after validation.
For canary deployments during feature releases, we'll implement gradual traffic shifting using service mesh or API gateway capabilities. The rollout will start with 5% of traffic to the new version, increasing by 10% increments every 15 minutes until full migration. Auto-rollback triggers will be configured based on error rate thresholds (5% error rate over 5 minutes) and latency degradation (>200ms p99 increase).
Artifact Promotion Model
The deployment pipeline follows a trunk-based development model with continuous integration. Artifacts are promoted through environments in the following sequence:
- Dev Environment: Automated unit and integration tests run on every commit to main branch
- Staging Environment: Full end-to-end testing including load and performance tests with 10% of production traffic
- Production Environment: Blue-green deployment with manual approval gates for critical features
Each environment has dedicated CI/CD pipelines that validate code quality, security scanning (Snyk, Trivy), and compliance checks before artifact promotion.
Zero-Downtime Database Migration
Database migrations will be executed using online schema change tools (pt-online-schema-change for MySQL) to avoid table locks during updates. For major schema changes, we'll implement a feature flag-based approach where new columns or tables are added in parallel with existing ones, and application logic is gradually migrated to use the new structure.
Feature Flag Integration
We'll integrate LaunchDarkly or Flagship for feature flag management to enable progressive rollouts and A/B testing. Feature flags will control:
- New email delivery protocols
- Different queue processing strategies
- A/B testing of content rendering engines
- Gradual rollout of new authentication methods
Canary Analysis Automation
Canary analysis will be automated using Spinnaker or Flagger with the following criteria:
- Error rate monitoring (target < 0.1%)
- Latency thresholds (p99 < 200ms)
- Throughput consistency checks
- Memory and CPU utilization patterns
Auto-rollback will be triggered when any metric exceeds predefined thresholds for 5 consecutive minutes.
Release Cadence and Branching Strategy
The system follows a trunk-based development model with:
- Main branch: Production-ready code, continuously deployed
- Feature branches: Short-lived, merged via pull requests with automated testing
- Release branches: Created only for hotfixes or major version releases
Release cadence is bi-weekly for minor features and monthly for major versions, with automated release notes generation and dependency version updates.
Rollback Strategy
In case of deployment failure:
- Immediate traffic shift back to previous stable version
- Automated alerting to on-call team with detailed failure analysis
- Rollback via API gateway or service mesh configuration changes
- Post-mortem analysis with root cause identification and mitigation planning
The rollback process is designed to complete within 5 minutes of failure detection, ensuring minimal impact on email delivery service availability.
17. Cost Architecture
Major Cost Drivers Analysis
Compute Costs (35-40% of total):
- EC2 instances for API services, workers, and background processing
- Kubernetes cluster nodes (EKS/AKS/GKE)
- Lambda functions for event-driven components
- Compute-intensive email rendering and template processing
Storage Costs (25-30% of total):
- Email content storage (metadata + full email bodies)
- Attachment storage in object store (S3/GCS)
- Database storage (PostgreSQL, Redis)
- Cache storage (ElastiCache/CloudMemorystore)
Network & Data Transfer Costs (20-25% of total):
- Ingress/egress traffic between services and external providers
- Email delivery to SMTP servers (outbound bandwidth)
- CDN distribution for email attachments and templates
- Cross-region replication costs
Database & Caching Costs (15-20% of total):
- Managed database services (RDS, CloudSQL)
- Redis/Memcached instances for caching
- DynamoDB/GCP Firestore for event storage
Cost Optimization Strategy per Layer
Compute Layer:
- Implement spot instances for batch processing and rendering jobs (20% cost reduction potential)
- Use provisioned concurrency for Lambda functions to reduce cold starts and optimize costs
- Implement auto-scaling with HPA and VPA to minimize over-provisioning
- Use multi-zone deployments to reduce cross-zone network costs
Storage Layer:
- Implement object storage tiering (S3 Standard-IA/Infrequent Access for older emails)
- Use database compression and archiving strategies to reduce storage footprint
- Implement cache eviction policies to minimize redundant data storage
- Use database read replicas for analytical queries to reduce primary DB load
Network Layer:
- Implement CDN for email attachment delivery to reduce bandwidth costs
- Use content-aware routing to minimize cross-region traffic
- Implement request compression for large email payloads
Reserved vs. Spot Instance Strategy
Reserved Instances (50% of compute):
- Use reserved instances for stable, predictable workloads (API services, core database)
- Apply 3-year reserved instances for long-term stable services
- Use convertible reserved instances for flexibility in workload types
Spot Instances (30% of compute):
- Deploy batch email processing jobs on spot instances (50% cost savings)
- Use spot instances for template rendering and content analysis
- Implement graceful degradation for spot instance interruptions
Data Egress Cost Minimization
Cross-Region Traffic Reduction:
- Deploy services in same region as databases and caches to minimize cross-region egress
- Use regional CDN endpoints for attachment delivery
- Implement local cache strategies to reduce repeated data fetches
Content Delivery Optimization:
- Use edge locations for email attachment delivery to reduce origin bandwidth costs
- Implement content compression and minification for email templates
- Use object storage with lifecycle policies to move older content to cheaper storage tiers
FinOps Dashboards and Budget Alerts
Cost Monitoring Dashboard:
- Build real-time cost monitoring dashboard with AWS Cost Explorer or GCP Billing Console
- Track per-service cost breakdowns and trends over time
- Implement cost allocation tags for better resource attribution
Automated Budget Alerts:
- Set up budget alerts at 75%, 90%, and 100% of monthly budget thresholds
- Configure alerts for specific services (e.g., S3 storage, EC2 compute)
- Implement automated cost optimization recommendations based on usage patterns
Cost Allocation Strategies:
- Use team-based tagging for better cost attribution
- Implement resource-level cost tracking for billing transparency
- Establish cost allocation models for shared services and infrastructure
Cost Optimization Metrics
Target Reductions:
- 25% reduction in compute costs through spot instance usage
- 30% reduction in storage costs via tiered storage and archiving
- 20% reduction in network costs through CDN and content optimization
- 15% reduction in database costs through read replica usage and compression
Monitoring KPIs:
- Monthly cost variance from budget (target: ±5%)
- Cost per email delivered (target: < $0.01)
- Compute utilization efficiency (target: > 70%)
- Storage efficiency ratio (target: > 85% compression/archiving)
18. Open Questions, Risks & Trade-offs
Decisions requiring product / engineering alignment
- Email content rendering strategy: Should we support rich HTML content with embedded assets or restrict to plain text + basic formatting? This impacts storage, caching, and rendering complexity.
- Delivery confirmation mechanisms: Should we implement read receipts, delivery confirmations, or just basic send status tracking? This affects system complexity and user expectations.
- Email template management: Should we support dynamic templates with parameterized content or static templates? This influences database schema design and template versioning strategy.
Key architectural risks
| Risk | Impact | Likelihood | Mitigation |
|---|---|---|---|
| Email delivery delays due to spam filtering | High (user experience) | Medium | Implement sender reputation monitoring, provide delivery status APIs, and maintain feedback loops with email providers |
| Message queue backpressure causing system degradation | High (system stability) | Medium | Implement circuit breaker patterns, queue length monitoring, and automatic scaling triggers |
| Cache invalidation causing stale content delivery | Medium (user experience) | High | Use cache tagging with TTLs and implement cache warming strategies |
| Multi-region email delivery inconsistency | High (user experience) | Medium | Implement consistent global state management and cross-region replication with eventual consistency model |
| Email content security vulnerabilities | High (compliance) | Low | Implement strict content validation, sandboxed rendering, and regular security audits |
Trade-offs made with justification
- Consistency vs. Availability: Chose AP in CAP theorem for email delivery service to prioritize availability over strong consistency, allowing for eventual consistency in read operations while ensuring all emails are delivered.
- Storage vs. Performance: Used a hybrid approach of in-memory caching and database storage to balance performance requirements with cost constraints, accepting that some data might be temporarily unavailable during cache misses.
- Horizontal Scaling vs. Complexity: Chose horizontal scaling with stateless services to support growth, accepting increased complexity in managing distributed state and inter-service communication.
- Real-time vs. Batch Processing: Implemented real-time delivery for critical emails and batch processing for marketing or newsletter emails to balance user experience with system efficiency.
- Custom Implementation vs. Third-party Services: Decided on custom implementation for core email delivery to maintain control over features and compliance, while integrating with third-party providers for spam filtering and deliverability.
Alternatives considered and rejected
- Monolithic architecture: Rejected due to scalability limitations and difficulty in maintaining different service levels for various email types (transactional vs. marketing).
- Full database sharding: Rejected due to complexity in maintaining cross-service relationships and increased operational overhead.
- External email service providers: Rejected due to compliance requirements, data sovereignty concerns, and need for custom features.
- Traditional SMTP-based delivery: Rejected due to complexity in handling modern email standards and security requirements.
- Event-driven microservices without message brokers: Rejected due to reliability concerns and the need for guaranteed delivery in email systems.
Technical debt acknowledged
- Email content sanitization: Current implementation uses basic regex-based filtering which may not cover all XSS and security vulnerabilities, requiring future enhancement with dedicated content sanitization libraries.
- Template versioning: Current template management lacks proper version control and rollback mechanisms, creating potential for breaking changes in email content.
- Cross-service dependency management: Inter-service communication lacks comprehensive error handling and fallback strategies, leading to potential cascading failures.
- Rate limiting implementation: Current rate limiting is basic and doesn't account for user behavior patterns or priority-based queuing, which may lead to unfair resource allocation.
- Monitoring and alerting gaps: Current observability stack lacks comprehensive end-to-end email delivery tracking, making it difficult to identify and debug delivery issues.
19. Phased Implementation Roadmap
Phase 1: MVP (Minimum Viable Product)
Timeline: 8-12 weeks Core Objective: Build foundational email delivery capabilities with basic reliability
Key Deliverables:
- Email ingestion service (SMTP/REST endpoint)
- Basic email queue processing with retry logic
- Simple SMTP relay to downstream providers (SendGrid, Amazon SES)
- Basic email tracking (delivered, opened, clicked)
- Single-region deployment with basic monitoring
- Email template rendering engine (handlebars/liquid)
- Basic authentication and authorization for senders
Dependencies:
- SMTP relay provider integration (SendGrid/AWS SES)
- Basic infrastructure provisioning (K8s cluster, DB instances)
- Core observability stack (logging, metrics, tracing)
Phase 2: Scale & Reliability
Timeline: 12-16 weeks Core Objective: Achieve horizontal scaling, multi-region support, and enhanced reliability
Key Deliverables:
- Multi-region deployment with active-active failover
- Horizontal sharding of email processing by sender domain or user
- Advanced retry and dead-letter queue handling with exponential backoff
- Enhanced email tracking with detailed analytics (open rates, bounce rates)
- Service mesh integration (Istio) for cross-service communication
- Automated load testing and performance benchmarking
- Multi-provider email delivery (SendGrid, AWS SES, Mailgun)
- Enhanced caching layer with L2 distributed cache
Dependencies:
- Multi-region VPC configuration and cross-region replication
- Service mesh setup and mTLS configuration
- Advanced observability with distributed tracing and alerting
- Multi-provider email delivery API integrations
Phase 3: Excellence & Optimization
Timeline: 16-24 weeks Core Objective: Achieve enterprise-grade reliability, observability, and cost optimization
Key Deliverables:
- Advanced analytics dashboard with real-time metrics
- Feature flag integration for progressive rollouts and A/B testing
- Comprehensive security enhancements (DDoS protection, WAF rules)
- Cost optimization with spot instances and storage tiering
- Advanced email personalization and segmentation engine
- Automated compliance reporting (GDPR, CAN-SPAM)
- Enhanced search capabilities for email content and metadata
- Multi-tenant support with resource isolation and quotas
Dependencies:
- Advanced security infrastructure (WAF, DDoS mitigation)
- Cost optimization tooling and dashboards
- Advanced analytics platform integration (ClickHouse, Redshift)
- Compliance and governance framework implementation
Critical Path Dependencies:
- Infrastructure Setup - VPC, K8s clusters, DB instances (Week 2-4)
- Core Service Development - Email ingestion and delivery services (Week 4-8)
- Provider Integrations - SMTP relay providers and tracking APIs (Week 6-10)
- Observability Stack - Logging, metrics, and tracing (Week 8-12)
- Multi-region Deployment - Cross-region replication and failover (Week 12-16)
Milestones:
- Week 12: MVP deployed to production with basic reliability
- Week 20: Multi-region support and horizontal scaling completed
- Week 32: Enterprise-grade features and cost optimization implemented
Risk Mitigation:
- Technical Debt: Dedicated sprint cycles for refactoring and optimization
- Provider Reliability: Multi-provider redundancy with fallback mechanisms
- Compliance: Early integration of compliance frameworks and audit trails
- Performance: Continuous load testing and capacity planning throughout all phases