18.1 How Email Works
Table of Contents
The Big Picture: How Email Moves Across the Internet
Email looks simple in your inbox, but behind every message there is a small “conversation” between multiple servers. As a backend developer, you do not need to become an email admin, but you must understand this flow, because you will often send registration emails, password reset links, and notifications from your applications.
At a high level, email works like this:
- A user or application composes an email.
- The email is submitted to an outgoing mail server.
- That server looks up where to send the email by checking DNS records.
- The sender server connects to the receiver server and delivers the message.
- The recipient’s mail server stores the email.
- The recipient’s email client fetches and displays the message.
We will walk through each part with practical examples that matter for backend development.
Key idea: An email is not sent “directly” from your app to someone’s inbox. It passes through one or more mail servers using standard protocols, especially SMTP for sending and IMAP/POP3 for receiving.
The Core Components in Email Delivery
Mail User Agent, Mail Transfer Agent, Mail Delivery Agent
There are three classic roles in the email world. Sometimes one program plays more than one role, but the concepts stay the same.
| Component | Also called | Who uses it | Typical examples |
|---|---|---|---|
| Mail User Agent (MUA) | Email client | Humans or apps | Gmail web UI, Outlook, Apple Mail, Thunderbird |
| Mail Transfer Agent (MTA) | Mail server | Servers talk to servers | Postfix, Exim, Sendmail, Microsoft Exchange |
| Mail Delivery Agent (MDA) | Local delivery | Server stores mail for users | Dovecot LDA, Procmail, built into some MTAs |
In many modern setups:
- Your application acts as a simple MUA, or uses a library that acts as one.
- A transactional email provider (for example, SendGrid, Mailgun, Amazon SES) acts as the MTA and MDA for sending.
- Users read emails with a web interface or mobile app, which are MUAs that talk to provider MTAs and MDAs.
As a backend developer, your code usually:
- Creates the email content (subject, body, headers).
- Talks to an SMTP server (via a library) to submit the message.
- Lets the email infrastructure deliver and store the message.
Step‑by‑Step: What Happens When You Send an Email
Imagine your application lives at api.myapp.com and you send a welcome email to alice@example.com.
We will follow the path:
- App → Outgoing mail server (SMTP submission)
- Outgoing mail server → DNS lookup for
example.com - Outgoing mail server → Recipient mail server (SMTP delivery)
- Recipient mail server → Recipient mailbox
1. Your Application Submits the Email
Your app prepares an email, which at the protocol level is a plain text document with headers and a body, for example:
From: "MyApp" <no-reply@myapp.com>
To: Alice <alice@example.com>
Subject: Welcome to MyApp
Date: Fri, 01 Jan 2026 10:00:00 +0000
Message-ID: <abc123@myapp.com>
Content-Type: text/plain; charset="utf-8"
Hi Alice,
Welcome to MyApp!
Best,
The MyApp TeamYour app then:
- Connects to an SMTP submission server, often on port 587 with TLS (STARTTLS).
- Authenticates with a username and password, or API key.
- Sends the message to the server.
Typical scenarios:
- You connect directly to your own SMTP server, for example
smtp.mycompany.com. - You use a cloud service, for example
smtp.sendgrid.net. - You avoid raw SMTP and call a provider’s HTTP API, which internally still sends via SMTP.
From your point of view:
# Pseudocode, not full implementation
send_email(
smtp_host="smtp.mailprovider.com",
username="apikey",
password="SECRET",
from_="no-reply@myapp.com",
to="alice@example.com",
subject="Welcome to MyApp",
body="Hi Alice..."
)
The mail provider now has the message and is responsible for getting it to example.com.
2. The Outgoing Server Uses DNS To Find the Recipient Server
To deliver to alice@example.com, the mail server must find where example.com receives mail.
It asks DNS: “What are the MX records for example.com?”
An MX record says: “Mail for this domain should go to this host.”
Example DNS for example.com:
| Record type | Name | Value | Priority |
|---|---|---|---|
| MX | example.com. | 10 mx1.example.com. | 10 |
| MX | example.com. | 20 mx2.example.com. | 20 |
The server:
- Queries DNS for
MX example.com. - Gets a list of mail hosts (here
mx1.example.comandmx2.example.com). - Chooses the lowest priority number first (10 before 20).
- Resolves
mx1.example.comto an IP address using an A or AAAA record.
Important rule: Email delivery uses MX DNS records to find the correct mail server for the recipient’s domain. Without MX records, many servers will not know where to send email.
If mx1.example.com is down, the sender will try mx2.example.com.
3. SMTP Conversation Between Mail Servers
Now the sender’s MTA opens a TCP connection, usually to port 25, on mx1.example.com, and speaks SMTP.
A very simplified conversation looks like this:
S: 220 mx1.example.com ESMTP Ready
C: EHLO smtp.mailprovider.com
S: 250-mx1.example.com Hello
S: 250-SIZE 52428800
S: 250-PIPELINING
S: 250 8BITMIME
C: MAIL FROM:<no-reply@myapp.com>
S: 250 2.1.0 Ok
C: RCPT TO:<alice@example.com>
S: 250 2.1.5 Ok
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: From: "MyApp" <no-reply@myapp.com>
C: To: Alice <alice@example.com>
C: Subject: Welcome to MyApp
C:
C: Hi Alice,
C:
C: Welcome to MyApp!
C:
C: .
S: 250 2.0.0 Queued as XYZ123
C: QUIT
S: 221 2.0.0 ByeKey points:
MAIL FROMis the envelope sender, not always the same as theFrom:header.RCPT TOis the envelope recipient, one per recipient.- After
DATA, the server transmits the full email content until a line with a single..
If everything is accepted, the recipient server will keep the message and either:
- deliver it to a local mailbox (for example, for
@example.comusers), or - forward it to another server, if configured as a relay.
4. Recipient Server Stores the Email
Once the recipient’s MTA accepts the message, it must deliver it to the user’s mailbox. This is where MDA-like functionality happens.
For a hosted email provider, typical flow:
- MTA receives email for
alice@example.com. - It looks up Alice’s account and mailbox.
- It applies filters, such as spam checks and rules.
- It stores the message in the right folder, for example Inbox.
Emails are usually stored in formats like Maildir or in a database-like storage in large systems. From your perspective as a backend developer, the details of local storage rarely matter, unless you work directly on mail infrastructure.
How Recipients Read Email
There are two main protocols for reading emails from a server:
- IMAP: Internet Message Access Protocol, lets clients manage mail on the server, supports folders, flags such as "read" or "starred".
- POP3: Post Office Protocol v3, older, typically downloads and optionally deletes mail from the server.
Users rarely see these names anymore, because:
- Webmail (Gmail, Outlook.com) hides them behind a web interface.
- Mobile and desktop apps configure them automatically.
Typical flows:
- The email client connects via IMAP to
imap.example.comon port 993 with TLS. - It authenticates as
alice@example.com. - It lists mailboxes, fetches messages, marks them as read, moves them, and so on.
As a backend developer building a web application, you usually:
- Do not implement IMAP or POP3 yourself.
- Let users use their email providers, while your backend only sends messages.
SMTP vs IMAP vs POP3: What You Must Remember
| Purpose | Protocol | Typical Port (with TLS) | Used by |
|---|---|---|---|
| Sending mail | SMTP | 587 (submission), 465 | Clients / Apps |
| Server-to-server send | SMTP | 25 | Mail servers (MTAs) |
| Reading / managing mail | IMAP | 993 | Email clients |
| Simple download | POP3 | 995 | Older email clients |
Rule to remember:
- SMTP is for sending and transferring emails.
- IMAP/POP3 are for retrieving emails.
Your backend normally only talks SMTP, or uses an HTTP API that wraps SMTP.
The Role of DNS in Email: MX, SPF, DKIM, DMARC (Overview)
You already saw MX records, which tell senders where to deliver mail. There are three other important DNS-based mechanisms that affect deliverability and security. You will use them often when configuring production systems, but their full details are covered in later chapters.
Here is a quick backend-focused overview.
MX: Where to Deliver Email
- Example MX record for
myapp.comif you use a provider:
myapp.com. IN MX 10 mx1.mailprovider.com.
myapp.com. IN MX 20 mx2.mailprovider.com.
This tells other servers: “Send mail for @myapp.com to mx1.mailprovider.com first, or mx2 if that fails.”
SPF: Who Can Send Email for Your Domain
SPF (Sender Policy Framework) is stored as a DNS TXT record and says which servers are allowed to send email for your domain.
Example:
myapp.com. IN TXT "v=spf1 include:_spf.mailprovider.com ~all"This means:
- Only servers listed in
_spf.mailprovider.comcan send as@myapp.com. ~allsays others are “soft fail” and likely suspicious.
For backend work, you will often see provider instructions like:
Add this SPF record to your DNS: v=spf1 include:sendgrid.net ~all.
DKIM: Cryptographic Signature for Email
DKIM (DomainKeys Identified Mail) uses a public/private key pair.
- Your provider signs outgoing messages with a private key.
- Receivers verify the signature by fetching the public key from a DNS TXT record.
Example DKIM record:
selector1._domainkey.myapp.com. IN TXT "v=DKIM1; k=rsa; p=PUBLIC_KEY_HERE"You usually:
- Enable DKIM in your email provider settings.
- Add a TXT record in your DNS with the provided name and value.
DMARC: Policy for Handling Failed SPF/DKIM
DMARC (Domain-based Message Authentication, Reporting and Conformance) tells recipients how strictly to treat messages that fail SPF or DKIM checks.
Example:
_dmarc.myapp.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@myapp.com"Meaning:
p=quarantinesuggests putting failing messages in spam.ruarequests reports sent todmarc@myapp.com.
For now, just remember: SPF, DKIM, and DMARC greatly impact whether your app’s emails land in Inbox or in Spam.
Message Routing, Relaying, and Queues
Real email flow is not always one hop from sender to recipient. There can be relays and queues.
Relays
A relay is an MTA that forwards email to another server.
Example flows:
- Your app → Internal relay → External provider → Recipient.
- Your app → Provider → Provider’s relay cluster → Recipient.
Reasons for relays:
- Central logging and filtering.
- Security policies that require one outgoing gateway.
- Load balancing and redundancy.
As a backend developer, you usually interact with a submission server and let it decide the internal relay path.
Queues and Retries
Sometimes the recipient server is:
- Temporarily down.
- Too busy.
- Temporarily refusing mail with a 4xx SMTP status.
In that case, the sending MTA:
- Puts the message in a queue.
- Retries after a delay, for a period (such as 1 to 5 days).
- If it finally cannot deliver, it sends a bounce message to the original sender.
Example issues that cause queueing:
- Network problems.
- DNS problems.
- Recipient server rate limiting.
Your application may see:
- Errors during SMTP submission, such as connection failures.
- Bounce notifications delivered to a special mailbox.
Handling retries in your app (background jobs, backoff strategies) is often separate from the MTA’s own retries but complements them.
Headers, Body, and MIME: What an Email Really Looks Like
An email is a text document divided into:
- Headers: key-value pairs at the top.
- A blank line.
- Body: the content.
Basic example:
From: "MyApp" <no-reply@myapp.com>
To: Alice <alice@example.com>
Subject: Welcome to MyApp
Date: Fri, 01 Jan 2026 10:00:00 +0000
Message-ID: <abc123@myapp.com>
Hi Alice,
Welcome to MyApp!Common headers:
| Header | Purpose |
|---|---|
| From | Human-visible sender |
| To, Cc, Bcc | Visible recipients |
| Subject | Subject line |
| Date | When the email was sent |
| Message-ID | Unique identifier for the message |
| Reply-To | Where replies should go |
| MIME-Version | Usually 1.0, indicates MIME usage |
| Content-Type | Text encoding, HTML vs plain text, etc. |
For richer content, such as HTML and attachments, emails use MIME (Multipurpose Internet Mail Extensions). You will see things like:
Content-Type: multipart/alternative; boundary="boundary123"Which means there are multiple parts inside, for example a plain text part and an HTML part.
For backend work:
- Libraries and providers handle MIME building for you.
- You typically set plain text and HTML bodies and maybe add attachments via API methods.
Example End‑to‑End Scenario for a Backend Developer
Imagine you implement:
- User registration that sends a verification email.
- Password reset that sends a reset link.
The high-level flow looks like this:
- User action
User signs up with emailalice@example.com. - Your backend generates a token
For example, a signed token valid for 24 hours. - Your backend builds the email
From: no-reply@myapp.comTo: alice@example.com- Subject: “Verify your email”
- Body containing a link
https://myapp.com/verify?token=... - Your backend sends via SMTP or provider API
- Connect to
smtp.mailprovider.com:587, or POST https://api.mailprovider.com/v3/sendwith JSON.- Provider handles delivery
- Uses DNS MX records of
example.com. - Talks via SMTP to the MX server.
- Retries or bounces on failure.
- Recipient reads
- Alice’s mail provider accepts the message.
- Stores it in her Inbox.
- Alice opens it using webmail or an app via IMAP/POP3.
Your concern:
- Correct configuration of sender domain in DNS (SPF, DKIM, DMARC).
- Using proper “From” addresses and return paths.
- Handling provider errors and bounced email events.
- Avoiding sending to non-existent or invalid addresses repeatedly.
Key Takeaways for Backend Developers
To close, here are the most important points to remember:
- Email flow: Client / App → SMTP server → DNS (MX) → Recipient server → Recipient client.
- SMTP is used to send and relay email, IMAP/POP3 to read it.
- MX records in DNS tell senders where to deliver email for a domain.
- SPF, DKIM, DMARC strongly affect whether your app’s emails reach the Inbox.
- Your backend usually uses an SMTP server or an email provider API, not raw protocol handling.
In the following chapters, you will learn how to use SMTP and providers in practice, send HTML and transactional emails, and integrate email sending into your backend applications safely and reliably.
Views: 8
KAHIBARO