Email — SMTP, POP, IMAP

Three protocols for one job. Why SMTP is push, POP/IMAP are pull, and where modern alternatives took over.

Building Block Foundational
8 min read
email smtp imap pop application-layer

What it is#

Email is one user-facing capability — “send a message to an addressable mailbox” — implemented by three protocols, each handling a different leg of the journey:

  • SMTP (Simple Mail Transfer Protocol, RFC 5321) — the push protocol. Used by sending mail clients to submit mail to their server, and by mail servers to forward mail to each other across the Internet. Port 25 between servers; 587 (with STARTTLS) or 465 (TLS-wrapped) for client submission.
  • POP3 (Post Office Protocol, RFC 1939) — the original pull protocol. Client connects to the mailbox server, downloads new messages, optionally deletes them server-side. Port 110, or 995 with TLS. Stateless and simple.
  • IMAP (Internet Message Access Protocol, RFC 9051) — the richer pull protocol. Client browses, searches, and selectively fetches messages that live server-side. Mailboxes are folders, state is synced. Port 143, or 993 with TLS.

A piece of mail typically traverses SMTP (sender’s MUA -> sender’s MTA -> recipient’s MTA), then waits in the recipient’s mailbox until they fetch it via IMAP or POP, or read it through a webmail interface that does the IMAP work server-side.

When to use it#

Email-the-system is still the universal asynchronous-messaging primitive — addressable across organisations, retained for years, audit-trail-friendly, recoverable via backups. Use it (or trigger sending it) when:

  • Inter-organisation async notification. Invoices, password resets, alerts, marketing.
  • You need delivery to people who don’t share your platform. Anyone with an email address can receive; no app install required.
  • You need persistent, addressable, archive-friendly messaging. Email’s long retention and search are still hard to match.

The protocols themselves (raw SMTP/IMAP) are mostly used:

  • By backend services to send transactional mail — via an SMTP relay (Postmark, SendGrid, SES) or a local MTA (Postfix).
  • By mail clients to read mailboxes — Apple Mail, Thunderbird, Outlook still speak IMAP.

Reach for something else when:

  • Real-time delivery matters. Use chat, push notifications, WebSocket.
  • You want guaranteed delivery semantics. Email is best-effort with retry; queueing systems (SQS, Kafka) give you actual delivery guarantees.
  • The receiver is your own system. Webhooks or message queues are cleaner than parsing mail.

How it works#

The end-to-end flow#

+----------+ SMTP +----------+ SMTP +----------+ IMAP +----------+
| sender | :587 | sender | :25 | recipient| :993 | recipient|
| MUA |--------->| MTA |--------->| MTA |<----------| MUA |
| (gmail. | | (smtp. | MX | (mx. | | (Apple |
| com web)| | gmail. | lookup | example.| | Mail) |
+----------+ | com) | in DNS | com) | +----------+
+----------+ +----------+
^ |
| v
queue, retry local delivery to mailbox

The chain is submission (MUA→MTA, port 587, authenticated) → relay (MTA→MTA, port 25, anonymous server-to-server) → mailbox store (recipient’s mailbox on disk) → retrieval (MUA→mailbox via IMAP/POP, authenticated).

SMTP, the wire#

SMTP is a text-based, line-oriented dialogue between client and server:

S: 220 mail.example.com ESMTP
C: EHLO sender.example
S: 250-mail.example.com Hello
S: 250 STARTTLS
C: STARTTLS
S: 220 Ready to start TLS
... TLS handshake ...
C: AUTH PLAIN base64(\0user\0pass)
S: 235 OK
C: MAIL FROM:<alice@sender.example>
S: 250 OK
C: RCPT TO:<bob@example.com>
S: 250 OK
C: DATA
S: 354 End data with <CRLF>.<CRLF>
C: From: Alice <alice@sender.example>
C: To: Bob <bob@example.com>
C: Subject: Hello
C:
C: Hi Bob.
C: .
S: 250 OK queued as 12345
C: QUIT

The single dot on its own line ends the data section (any line that starts with a dot must be doubled — “dot stuffing”).

How MTAs find each other#

Sender’s MTA does a DNS lookup on the recipient’s domain:

$ dig MX example.com +short
10 mx1.example.com.
20 mx2.example.com.

Lower priority number = higher preference. The MTA tries mx1 first; on failure, falls back to mx2. It then connects on port 25 and runs SMTP.

Authentication and anti-abuse#

SMTP itself authenticates only the submission step. Server-to-server traffic on port 25 historically had no authentication, which is how spam happened. The three standards that fixed it (or at least made spam fightable) live in DNS records:

  • SPF (Sender Policy Framework) — TXT record listing IPs allowed to send mail for the domain. Receiver checks the connecting IP against it.
  • DKIM (DomainKeys Identified Mail) — cryptographic signature in the message header; public key published in DNS. Receiver verifies signature.
  • DMARC — policy record saying what to do if SPF or DKIM fail (none, quarantine, reject), and where to send aggregate reports.

A modern email pipeline must implement all three or get filtered straight to spam.

IMAP, the wire#

IMAP is also text-based but each command is prefixed by a unique tag, and the server’s responses use that tag so the client can pipeline:

C: a001 LOGIN bob password
S: a001 OK LOGIN completed
C: a002 SELECT INBOX
S: * 18 EXISTS
S: * 2 RECENT
S: a002 OK [READ-WRITE] SELECT completed
C: a003 FETCH 18 (FLAGS BODY[HEADER])
S: ... headers ...
S: a003 OK FETCH completed
C: a004 LOGOUT
S: * BYE
S: a004 OK LOGOUT completed

IMAP is mailbox-stateful: messages have flags (\Seen, \Flagged, \Deleted), folders are first-class, search and partial fetch are server-side operations.

POP3, the wire#

C: USER bob
C: PASS password
C: STAT -> 5 1820 (5 messages, 1820 bytes)
C: RETR 1 -> ... message ...
C: DELE 1
C: QUIT

POP3 assumes a download-and-delete model — historical artefact of the days when mail was read on one device with slow, intermittent connectivity. Most clients now leave a copy on the server.

Variants#

  • ESMTP — extended SMTP. EHLO advertises capabilities (STARTTLS, AUTH, PIPELINING, 8BITMIME, SIZE). Universal in practice.
  • SMTP submission (port 587) — distinct from server-to-server SMTP. Authenticated, used by MUAs. Sometimes called “MSA” (Mail Submission Agent).
  • Implicit TLS (port 465, 993, 995) vs STARTTLS — implicit-TLS wraps the whole session in TLS from connect; STARTTLS upgrades a plaintext session in-band. STARTTLS is vulnerable to “STRIPTLS” downgrade attacks; MTA-STS and DANE help.
  • JMAP — modern JSON-over-HTTP replacement for IMAP (RFC 8620). Faster syncing, batch operations, supports calendar/contacts. Used by Fastmail; uptake elsewhere is slow.
  • MAPI / Exchange — Microsoft’s proprietary protocol for Exchange/Outlook. Not IMAP but solves the same problem in a richer, vendor-locked way.
  • Push protocols (ActiveSync, IMAP IDLE) — keep a connection open so the server can push new-message notifications. Closer to “real time” mail.

Trade-offs#

SMTP — push protocol, simple text dialogue, universally implemented, server-to-server interoperability. No authentication on the relay step (port 25); spam mitigation requires SPF/DKIM/DMARC layered on top. Delivery semantics are “best-effort with retry”.
IMAP / POP — pull protocols, retrieval from a mailbox. IMAP gives folders, server-side state, partial fetch, search; POP is download-and-go. Neither sends mail — they only retrieve. Both authenticated by design.
POP3 — simplest possible. Download, delete, done. Works offline. Single-device assumption — switching devices loses already-fetched messages.
IMAP — multi-device by design (messages stay server-side; flags sync). Folders, search, partial fetch. Heavier protocol; bad clients can hammer the server.

Other trade-offs:

  • Web vs native client — Gmail, Outlook on the web do all the IMAP/SMTP work server-side and present HTTP to the browser. Native clients still speak the protocols directly to the same mailbox.
  • Self-hosted vs managed — running your own mail server is technically straightforward and operationally painful (reputation, deliverability, abuse handling). Most teams use Postmark, SendGrid, SES, Mailgun for sending; Google Workspace or M365 for receiving.
  • Encryption — TLS on the hop is universal; end-to-end (PGP, S/MIME) is rare and hard to use. Email’s plaintext-at-rest is its defining privacy weakness.

Common pitfalls#

  • Submitting to port 25 from a client. Most ISPs block port 25 outbound (anti-spam). Use 587 (STARTTLS) or 465 (TLS) with authentication.
  • MX record points to a CNAME. RFC-disallowed; some receivers ignore the record. MX must resolve to an A/AAAA.
  • Missing SPF / DKIM / DMARC. Without all three, mail to Gmail/Outlook/Yahoo lands in spam — often silently with no bounce. Test with mail-tester.com style probes.
  • Open relay. An MTA that accepts mail from anyone for any recipient becomes a spam pipe within hours. Restrict relaying to authenticated submission only.
  • Confusing From, Sender, and Return-Path. From: is what the recipient sees; Sender: is the actual sender when different; Return-Path: (Envelope From) is where bounces go and what SPF validates against. Mismatches break DMARC alignment.
  • Trusting the IP in Received: headers. Each MTA adds one; the chain is forgeable below the trusted boundary.
  • Forgetting reverse DNS (PTR). Receivers commonly require the sending MTA’s IP to have a PTR record matching its HELO/EHLO name. Without it, you’re spam.
  • Long-lived IMAP IDLE connections behind NAT. NAT entries time out; the IDLE connection silently dies. Configure keepalive or periodic NOOP.
Why has email survived for 50 years when nothing else has?

Three reasons. Decentralisation by protocol. No single operator can shut down email — every domain runs its own MX. Universal addressing. user@domain is an addressable identifier owned by the user (in spirit). Forward compatibility. SMTP from 1982 still interoperates with modern receivers; the protocol grew (ESMTP, AUTH, STARTTLS, MIME, SPF, DKIM, DMARC) without breaking the wire. Every replacement attempt — XMPP, RSS, walled-garden chat — has either failed to dethrone it or shrunk to a niche. Email’s victory is a victory of protocol design, not feature design.

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.