- Why self-host email in 2026
- The capability model
- Sender reputation on a residential IP
- Hygiene: SPF, DKIM, DMARC, MTA-STS
- Day-to-day operations
- When it breaks
- Takeaways
Why self-host email in 2026
Email is the only protocol on the open internet that still routes mail to a machine you control. Every other surface — chat, calendar, social — has quietly migrated to platforms where your identity lives at the pleasure of a vendor. SMTP didn’t move. The protocol still says: if you can run a daemon on port 25, accept TLS, present a valid DKIM signature, and stay out of the blocklists, you get to talk.
That’s a narrowing window. Gmail, Outlook, Yahoo — together about 80% of inbound mail destinations — have spent the last four years tightening sender requirements. Google’s 2024 bulk-sender rules made it formal: no DKIM, no DMARC, no easy unsubscribe, no delivery. Most operators read that as “self-hosting is dead.” It isn’t — but it became a real engineering problem rather than a hobby project. That’s exactly the kind of problem worth solving in-house.
The bet behind this stack: if I can keep the mail ingress reachable, signing every outbound message, scoring inbound for spam locally, and staying off the public blocklists for three years running, I don’t owe Google an inbox. I owe them a relay-equivalent reputation, which is a much easier debt to service.
Email is the last protocol where running your own server still buys you something other than nostalgia. — Operating principle, mail domain
The capability model
The private runtime is split into four roles: transport, mailbox state, filtering/signing, and human administration. Those roles are intentionally described here as outcomes instead of a public bill of materials. A visitor should understand the operating discipline without learning service names, process names, or where the controls live.
- Transport accepts inbound mail and hands outbound mail to a clean relay path.
- Mailbox state keeps user data durable, searchable, and recoverable.
- Filtering and signing score inbound mail, quarantine obvious badness, and cryptographically sign outbound mail.
- Administration is operator-only and does not need a public URL to feel real.
PUBLIC VIEW
transport live private route hidden
mailboxes live topology redacted
filtering live policy summarized
admin gated SSO required
Sender reputation on a residential IP
The hardest part isn’t the software. It’s the fact that a residential ISP IP block sits on at least three blocklists by default. The Spamhaus PBL (Policy Block List) lists every dynamic-IP range in the world; Sorbs adds another layer; Spamcop flags any IP that’s ever been part of a botnet, which most residential ranges have been at some point.
The fix isn’t to argue with the lists. The fix is to relay. Outbound mail from this server doesn’t try to deliver itself to gmail-smtp-in.l.google.com. It hands the message to a paid transactional relay that owns clean, warmed IP space — currently Postmark for personal mail and a separate provider for any list/marketing flow. The relay does the actual MX-to-MX hop. My server just signs and authenticates.
Inbound is the opposite problem and a kinder one: any server on the internet is allowed to attempt delivery, and the private filtering layer does the discriminating. You get the full firehose, you score it, you drop or quarantine 90%+, the rest lands in the inbox.
Hygiene: SPF, DKIM, DMARC, MTA-STS
Four DNS records do most of the work. They don’t change often. When they’re wrong, nothing works. When they’re right, the system disappears.
SPF
Tells receivers which IPs are allowed to send From: your domain. Mine looks like:
system-ai-x.com TXT "v=spf1 include:spf.postmarkapp.com -all"
The -all matters. ~all (soft-fail) leaves the door open; -all (hard-fail) tells the receiver to reject anyone not on the list. Lazy operators use ~all so things don’t break when they forget to add a sender. That’s how phishing campaigns get permission to ride your name.
DKIM
A cryptographic signature on every outbound message, anchored in DNS:
[selector]._domainkey.[mail domain] TXT "v=DKIM1; k=rsa; p=..."
The private signing layer signs every outbound message, the receiver fetches the public key, verifies, and now the From: line is provably mine. Rotating this key annually is the only maintenance ritual that has to be on a calendar.
DMARC
The policy layer on top:
_dmarc.[mail domain] TXT "v=DMARC1; p=reject; rua=mailto:dmarc@[mail domain]"
“If SPF or DKIM fails, reject the message, and email me a report.” That’s the strictest setting. It’s also the only setting that closes the loop — anything weaker tells phishers they have wiggle room.
MTA-STS
The newest addition, and the one most operators skip. It tells receivers: “always negotiate TLS to my MX, and if you can’t, drop the message.” It is served by a tiny nginx pod next to the mail stack.
Day-to-day operations
The reason this stack is sustainable is that 99% of weeks it does nothing visible. The operator surface is:
- A private health panel showing inbound vs. outbound rates, rejection rate, and queue depth.
- A private log query for blocked mail and delivery anomalies.
- A weekly operator review of workload health from inside the trust boundary.
- A monthly look at the DMARC aggregate reports to see if anyone is trying to spoof the domain (someone always is).
Mail accounts are created via the admin UI — about 30 seconds per account. Aliases (which is most of what gets created) take five seconds. Forwarders to old Gmail addresses are an alias plus an external destination; the system is happy to fan-out.
When it breaks
Three failure modes have shown up across three years:
1. Certificate expiry. The certificate layer renews on a schedule, but the first rotation did not wake the outbound transport. The fix was a small reconciler that watches the certificate secret and reloads the private delivery layer on rotation. Two-line patch, two-day debug.
2. Disk fill from logs. A filtering corpus grew until it pressured the storage layer. The fix was scheduled pruning. The signal of the problem was the mailbox UI going read-only — not the obvious diagnosis.
3. Greylist deadlock during DNS outage. When upstream resolution wobbled, the greylist module retried every inbound, the queue grew, transport throttled, and a backlog formed. The fix was multi-resolver redundancy and a circuit breaker on greylisting.
Every failure mode of a mail server is a small, dignified disaster that takes one weekend to find and ten minutes to fix once you do. — Notes after the third year
Takeaways
The aim was never “save money.” It was identity sovereignty — owning the address that every other service uses to verify me. If Google’s mood changes about my account tomorrow, my inbox doesn’t move with it. The keys live in a vault I control. The records are signed by a domain I own. The mail keeps arriving.
It costs about $7 a month in relay fees and roughly two hours a month in operator attention. Compared to the value of an address that has been continuously mine since 2018, that’s the cheapest infrastructure on this whole cluster.