Design an Email System
Email is one of the oldest and most resilient communication protocols on the internet. Every day, over 300 billion emails are sent and received globally. Platforms like Gmail, Outlook, Yahoo Mail, Proton Mail, and countless enterprise mail servers must handle massive throughput, store petabytes of data, filter out spam, and maintain near-perfect availability. Designing a reliable, scalable email system involves deep understanding of asynchronous messaging protocols (SMTP, IMAP, POP3), distributed storage, search indexing, and security. This article walks through a complete architectural design for a modern, cloud-native email service.
Step 1: Requirements Clarification
Functional Requirements
- Send email – Users can compose and send emails to one or more recipients.
- Receive email – The system accepts incoming emails from external servers and delivers them to the appropriate mailbox.
- Store email in mailbox – Emails are persisted and organized into folders or labels.
- Support attachments – Users can attach files (images, documents) to emails.
- Search mail – Users can search across their entire mailbox by subject, body, sender, or attachment content.
- Spam filtering – Incoming emails are evaluated and spam is either rejected, quarantined, or delivered to a spam folder.
- Forwarding and replying – Common email actions.
- Multi-device sync – A user’s mailbox state (read/unread, folders, sent items) is consistent across web, mobile, and desktop clients.
- Folder / label management – Users can create, rename, and delete organizational labels.
Non-Functional Requirements
- High availability – Email is considered mission-critical; the service should be available 99.95% or higher.
- Reliable delivery – The system must not permanently lose accepted emails. It should retry delivery for a reasonable period and notify senders of permanent failures.
- Low latency for sending – The send action should feel instantaneous; actual delivery may be asynchronous.
- Scalability – The system must handle billions of users and trillions of messages.
- Security – Emails must be encrypted in transit, and the system must protect against unauthorized access, spoofing, and data breaches.
- Spam and abuse prevention – Robust filtering to maintain sender reputation and protect recipients.
- Message durability – Once accepted, a mail must survive hardware failures.
- Fault tolerance – Failures in individual components should not cause data loss or extended downtime.
Step 2: Capacity Estimation
Assume a large-scale email provider:
- Total users: 1 billion
- Daily active users: 500 million
- Emails received per user per day: 40
- Emails sent per user per day: 10
- Total incoming emails per day: 20 billion
- Incoming emails per second (peak): assuming 2x peak, ~460,000 emails/sec
- Storage per email (average): 50 KB including metadata and headers; attachments average 200 KB
- New storage per day: (20B * 50KB) + attachment volume; approx 1 PB/day for text and several PB/day for attachments
- Mailbox reads: 500M users checking mail multiple times per day; read QPS in the millions
Email systems are write-heavy on the receiving side (high ingestion rate) and read-heavy on the mailbox side (frequent fetches, search).
Step 3: API Design
The system exposes a RESTful API for client applications and an internal API for mail transfer agents.
REST APIs (simplified)
-
Send email
POST /api/v1/messages/send
Body:{ to[], cc[], bcc[], subject, body, attachments[] }
Returns{ message_id, status: "queued" } -
Fetch mailbox
GET /api/v1/mailboxes/{folder}?page_token={token}&limit=50
Returns a paginated list of message summaries (sender, subject, snippet, timestamp, read/unread). -
Get single email
GET /api/v1/messages/{message_id}
Returns full message content including body and attachment download URLs. -
Search emails
GET /api/v1/search?q={query}&folder={folder}
Returns matching message summaries. -
Upload attachment
POST /api/v1/attachments
Multipart upload returning anattachment_idto include in the send call. -
Modify labels / folders
POST /api/v1/messages/{message_id}/labels
Body:{ add_label_ids[], remove_label_ids[] }
Idempotency is achieved by generating a unique message_id on send and deduplicating by that ID.
Step 4: High-Level Architecture
- API Gateway: Authenticates requests and routes to services.
- Mail Submission Service: Accepts outgoing mail from authenticated users, applies sending limits, and queues the message.
- SMTP Relay / MTA (Mail Transfer Agent): Handles communication with external SMTP servers for outgoing mail and accepts incoming mail from other domains.
- Message Queue: Decouples submission from delivery, allowing buffering, retries, and load leveling.
- Spam Filter: Analyzes incoming and outgoing messages for spam, phishing, and malware.
- Mail Delivery Service: Stores accepted messages into the recipient’s mailbox and updates search indexes.
- Mailbox Storage: Persistent, sharded database holding all user mailboxes.
- Search Index: Full-text search index built from mailbox data.
- Attachment Store: Scalable object storage for attachments.
- CDN: Accelerates attachment downloads globally.
Step 5: Email Delivery Flow
The sending and receiving pipeline involves multiple stages.
Outgoing Email (User → External Recipient)
- User composes mail and hits send.
- Submission Service authenticates user, checks rate limits, applies outgoing spam policies.
- Message is written to a message queue for asynchronous processing.
- A worker picks up the message, performs final validation, and passes it to the MTA.
- The MTA looks up the recipient’s domain MX record via DNS, establishes an SMTP connection to the recipient’s mail server, and delivers the message.
- If delivery fails temporarily (e.g., recipient server is down), the MTA queues the message for retry with exponential backoff up to a configured maximum (often 24-48 hours). After that, a bounce message is generated and returned to the sender.
Incoming Email (External → Local Mailbox)
- An external MTA connects to our inbound SMTP servers.
- The inbound MTA performs initial checks (reverse DNS, SPF, DKIM, DMARC).
- The message is placed on the incoming queue.
- Spam Filter analyzes the message (content, reputation, machine learning models) and assigns a spam score.
- If the score is above a rejection threshold, the message is refused during the SMTP session. Otherwise, it may be delivered to the inbox or to the spam folder.
- Mail Delivery Service writes the message to the recipient’s mailbox in Mailbox Storage, updates indexes, and triggers Notification Service to push an alert to the user’s devices.
Step 6: SMTP and Mail Transfer Protocols
Email relies on a set of standard protocols:
| Protocol | Purpose |
|---|---|
| SMTP (Simple Mail Transfer Protocol) | Pushes mail from sender to recipient’s mail server. Used between MTAs and from client to submission server. |
| IMAP (Internet Message Access Protocol) | Allows clients to manage and read mail directly on the server. Supports folders, flags, and partial fetch. Stateful. |
| POP3 (Post Office Protocol v3) | Downloads mail to the client and optionally deletes it from the server. Simpler but less suitable for multi-device sync. |
Modern systems use SMTP for transport and IMAP (or a proprietary REST/WebSocket API) for mailbox access, with POP3 available for legacy clients.
Step 7: Mailbox Storage Design
Each user has a mailbox that can contain hundreds of thousands of messages. The storage must support:
- Fast listing by folder, sorted by date or thread.
- Quick retrieval of individual messages.
- Atomic updates to labels (read/unread, starred, folder moves).
Schema considerations:
- A
messagestable partitioned by user ID, containing message metadata (sender, recipients, subject, timestamp, thread ID) and a reference to the full content stored separately (or inline for small emails). - A
labelsmapping table associating message IDs with label IDs. - Attachments stored as separate objects; the message contains
attachment_idand metadata.
SQL vs NoSQL:
| Aspect | SQL (e.g., PostgreSQL) | NoSQL (e.g., Cassandra) |
|---|---|---|
| Schema flexibility | Less flexible; requires migrations for new features. | Highly flexible, dynamic columns. |
| Secondary indexes | Rich indexing support. | Limited; may need separate index tables or search engine. |
| Scaling writes | Harder to shard; usually requires application-level partitioning. | Naturally scales with partitioning by user. |
| Consistency | Strong; ACID transactions. | Tunable; often eventual consistency. |
| Typical use | Metadata, user settings, labeling. | Massive mail storage with per-user partitioning. |
A common pattern is to use a relational database for user accounts, settings, and label mappings, and a NoSQL wide-column store for the message body store, sharded by user ID.
Step 8: Spam Filtering and Abuse Prevention
Spam filtering is a multi-layered defense:
- Connection-time checks: Reverse DNS, SPF (Sender Policy Framework), DKIM (DomainKeys Identified Mail), DMARC (Domain-based Message Authentication, Reporting, and Conformance) validate sender authenticity.
- Reputation scoring: IP and domain reputation databases (DNSBLs) block known bad actors.
- Content analysis: Machine learning models (Bayesian, neural networks) evaluate subject, body, links, and attachment types for spam characteristics.
- User feedback: Users marking mail as spam or not spam provides continuous training signals.
- Rate limiting: Limit the number of messages a user can send per hour to prevent spam accounts from blasting.
- Outbound filtering: Prevents compromised accounts from damaging the sending IP reputation of the entire service.
Bounces and complaint feedback loops (FBL) from ISPs help identify unwanted mail and automatically unsubscribe or block future delivery.
Step 9: Search and Indexing
Email search requires full-text indexing of subject, body, and attachment content.
- An indexing pipeline processes new messages as they arrive, extracting text and metadata and writing to a Search Index cluster (e.g., Elasticsearch).
- The index is partitioned by user ID, so a search query is scoped to a single user’s data.
- Searches support advanced filters:
from:,to:,has:attachment,newer_than:, etc. - Index updates are asynchronous; a slight delay (seconds) between receiving a mail and its searchability is acceptable.
Trade-off: To reduce write amplification, body content may be indexed in a lazy fashion or only when the user first searches.
Step 10: Attachments and Media Handling
Attachments are uploaded before or during the compose flow and stored separately from email content.
- User uploads a file via the API. The file is placed in Object Storage (e.g., S3).
- An antivirus scan is performed asynchronously. If malware is detected, the file is quarantined and the user is notified.
- The upload endpoint returns an
attachment_id. The client attaches it to the outgoing message. - On the recipient side, attachment download links are signed URLs pointing to the CDN, reducing bandwidth on origin storage.
- Attachments have file size limits (e.g., 25 MB per message) and are automatically expired after a configurable period if not associated with a message.
Step 11: Scalability Strategies
- Horizontal scaling: All services (submission, MTA, delivery, API) are stateless and scale out behind load balancers.
- Queue-based delivery: The message queue acts as a buffer, allowing workers to process at their own pace and smoothing traffic spikes.
- Mailbox sharding: Mailbox storage is partitioned by
user_id. This distributes both reads and writes evenly. - Read replicas: For SQL metadata stores, read replicas handle listing and search traffic.
- Caching: A distributed cache (Redis) holds recent mailbox listings and frequently accessed messages to reduce database load.
- Backpressure: If the queue depth or database latency exceeds safe thresholds, the system can temporarily slow acceptance of new incoming mail (via SMTP 4xx temporary failures) rather than crash.
- Multi-region deployment: Inbound SMTP gateways are deployed in multiple regions; user data is geo-located to a home region, while edge delivery ensures low-latency mailbox access globally.
Step 12: Reliability and Failure Handling
- Delivery retries: SMTP delivery employs exponential backoff; typical retry for up to 48 hours. After that, the sender gets a bounce.
- Deferred mail: If the delivery service or mailbox storage is temporarily unavailable, the message remains in the queue; it is not lost.
- Dead-letter handling: Messages that cannot be delivered even after retries (due to permanent errors) are placed in a dead-letter topic for inspection.
- Sender reputation: Consistent delivery failures to a domain can lower our IP reputation; monitoring and automatic throttling prevent this.
- Partial outages: If the search index is down, users can still read and send email; only search is degraded.
- Failover: SMTP gateways use DNS-based failover. Database clusters use automatic leader election. Object storage is inherently highly available.
- Disaster recovery: Mailbox data is replicated across availability zones and backed up to a separate region.
Step 13: Security and Privacy
- Authentication: OAuth 2.0 or strong passwords with MFA. App-specific passwords for IMAP/POP3.
- Authorization: Users can only access their own mailbox data.
- TLS in transit: All SMTP, IMAP, and HTTPS connections are encrypted.
- Encryption at rest: Mailbox data and attachments are encrypted using AES-256.
- Attachment scanning: Protects users from malware.
- Anti-phishing: Inline detection and warning banners for suspicious links. DMARC enforcement prevents domain spoofing.
- Account recovery: Resets via secondary email or phone; risks of social engineering require strong verification.
Real-World Example: Gmail-like Email System
Consider a Gmail-like service with conversation threading, labels, and powerful search.
- Alice sends an email; it passes through outgoing spam checks, is queued, and delivered via SMTP to Bob’s server.
- Bob’s reply arrives at our inbound SMTP gateway, is scanned, and then placed into the queue.
- Delivery service stores the message in Alice’s mailbox, indexes it, and triggers a push notification.
Trade-offs
- Latency vs reliability: Immediate delivery feels fast but risks losing mail if the recipient server is temporarily down. Asynchronous queuing with retries provides reliability but may add slight delay.
- Spam protection vs delivery speed: Aggressive filtering reduces spam but may delay or incorrectly block legitimate email (false positives). Continuous tuning balances both.
- Storage cost vs retention: Storing all emails forever is costly. Providing generous quotas (15 GB free) with the option to purchase more is a common model.
- Search indexing vs write throughput: Real-time indexing of every message adds write load; delaying indexing slightly reduces cost but makes recent messages unsearchable for a short time.
- Strong consistency vs availability: During a network partition, preferring availability may show inconsistent mailbox states across devices briefly; preferring consistency ensures correctness but may reject writes.
Common Mistakes
- Treating email as instant messaging – Email delivery is asynchronous by nature; expecting sub-second delivery to external domains misunderstands SMTP.
- No retry strategy – Without proper retry queues and bounce handling, mail can be silently lost.
- Ignoring spam and abuse – A single compromised account or open relay can blacklist the entire IP range, blocking all mail from the service.
- Storing attachments directly in the database – Blob storage in relational databases doesn’t scale well; use object storage.
- Weak search indexing – Users expect instant, Gmail-like search; a poor indexing strategy leads to slow, unusable search.
- No mailbox sharding plan – As user count grows, a single database instance becomes a bottleneck. Partitioning by user must be designed upfront.
- Not handling deferred SMTP delivery – External servers often return 4xx temporary failures; the system must respect these and retry later.
Interview Perspective
In system design interviews, an email system question tests your understanding of asynchronous protocols, storage, and filtering. Expect questions like:
- How does SMTP work?
- How do you store billions of mailboxes?
- How do you prevent spam?
- How do you implement search over email?
- How do you ensure reliable delivery?
- What trade-offs exist between IMAP and a custom API?
Demonstrate that you see email as a combination of store-and-forward queues, scalable data partitioning, and robust filtering.
Summary
An email system is a complex, asynchronous, globally distributed communication platform. It combines SMTP for message transport, queue-based architecture for reliable delivery, sharded mailbox storage for massive scale, layered spam filtering for security, and full-text search indexing for usability. Balancing reliability, latency, storage costs, and security is at the heart of the design. By applying the patterns and strategies discussed here, you can architect a modern email service that competes with industry leaders.