Skip to content
Go back

Self-Hosted Email in 2026: Mailcow vs Mailu vs Stalwart

By SumGuy 11 min read
Self-Hosted Email in 2026: Mailcow vs Mailu vs Stalwart

You Were Warned. Now Let’s Talk Anyway.

Everyone who has ever touched a Linux forum, a selfhosted subreddit, or a Discord server for homelabbers has received the same sermon: do not self-host email. Port 25 will be blocked. Gmail will silently drop your messages. Your IP will be on three blacklists before you finish typing postfix reload. You will spend your Saturday debugging SPF alignment while your actual email sits unread.

That sermon is correct. It is also incomplete.

Because here’s what they don’t tell you: there are real people running real self-hosted mail stacks right now, delivering to Gmail, Outlook, and Fastmail without incident. They chose the right VPS provider. They warmed their IP slowly. They nailed their DNS records on the first try (or the third, but who’s counting). And they now have full ownership of their own mail infrastructure, no vendor lock-in, and a faint sense of smug satisfaction.

This article is for those people — or the people who want to become them. We’re comparing three serious options: Mailcow, Mailu, and Stalwart. We’ll cover deliverability reality, VPS selection, DNS records that actually matter, and the exact moment you should stop fighting and go pay someone else.


The Deliverability Minefield (Non-Negotiable Reading)

Before we talk stacks, we need to talk about the battlefield.

Self-hosted email in 2026 is not a technical problem. The software is solid. The problem is reputation — specifically, the reputation of your IP address, your domain, and your sending patterns. The big mail providers have spent years building ML-backed filtering systems that are extraordinarily good at flagging new senders, residential IPs, and anything that looks like spam infrastructure.

Here’s what you’re up against:

Blacklisted IP ranges. AWS, GCP, Azure, DigitalOcean, Linode — their entire IP ranges are either outright blocked for SMTP or heavily tarpitted. You cannot run a real mail server on these. Don’t try. The providers that work in 2026: OVH, Hetzner, Vultr (with abuse@vultr ticket to unblock port 25), Contabo (reputation varies), and dedicated mail-friendly hosting like Pair Networks or Greenhost.

Port 25 blocking. Your VPS provider may block outbound port 25 by default. This is not an ISP thing — it’s deliberate provider policy. Before you spend three hours installing Mailcow, verify: telnet smtp.gmail.com 25. If it times out, file a ticket. Hetzner will unblock it in a day. Some providers never will.

Reverse DNS. Your mail server’s hostname must have a matching PTR record. mail.yourdomain.com must resolve to your VPS IP, and your VPS IP’s PTR must resolve back to mail.yourdomain.com. Most providers let you set this in the control panel. Do it before you send a single message.

SPF, DKIM, and DMARC. These are not optional. They are table stakes. No valid SPF record means your email goes to spam. No DKIM signature means it goes to spam. No DMARC policy means Gmail will start deprioritizing you in 2026 because they’ve been tightening requirements every six months. We’ll cover the exact records below.

IP warmup. A fresh IP is an unknown IP. Send 10 emails the first day. 50 the second. 200 the third. Ramp over two to four weeks. If you send a blast on day one, you’ll get rate-limited or blocked and it will take months to recover. This is not negotiable.

Now let’s look at the three stacks.


Mailcow: The Battle-Tested Workhorse

Mailcow has been around since 2016. It runs Postfix (SMTP), Dovecot (IMAP), Rspamd (spam filtering), ClamAV (antivirus), SOGo (webmail), and a handful of supporting services — all orchestrated by Docker Compose. The web UI is genuinely good. The documentation is comprehensive. The community is active and opinionated.

Who it’s for: Anyone who wants a feature-complete mail server and doesn’t mind running a dozen containers. Mailcow is what you reach for when you want Outlook-style webmail, multiple domains, shared calendars, and a UI that your less technical family members could actually use.

The setup reality: Clone the repo, run the installer script, configure a few environment variables, point your DNS records at it, and you’re mostly there. Mailcow’s installer handles the Compose file generation. The hard part is DNS and waiting.

docker-compose.yml
# Mailcow is NOT configured via a hand-rolled Compose file.
# Use the official installer:
# git clone https://github.com/mailcow/mailcow-dockerized
# cd mailcow-dockerized
# ./generate_config.sh
# It produces mailcow.conf and docker-compose.yml for you.
# Minimum specs: 4 vCPU, 6 GB RAM, 20 GB disk.
# Below is a simplified excerpt showing the network shape:
services:
postfix-mailcow:
image: mailcow/postfix:latest
restart: always
ports:
- "25:25"
- "587:587"
- "465:465"
networks:
- mailcow-network
dovecot-mailcow:
image: mailcow/dovecot:latest
restart: always
ports:
- "993:993"
- "995:995"
- "143:143"
networks:
- mailcow-network
rspamd-mailcow:
image: mailcow/rspamd:latest
restart: always
networks:
- mailcow-network
networks:
mailcow-network:
driver: bridge

The catch: Mailcow is hungry. It wants at least 6 GB of RAM when ClamAV is running. You can disable ClamAV to drop to 3–4 GB, but then you’re running without antivirus scanning. The full stack is 15+ containers. On a $6/month VPS this isn’t running. Budget for a €8–12/month Hetzner CX32 at minimum.

Verdict: If you’re running email for a small team, need shared calendars, or want the most mature option in this list, Mailcow is it.


Mailu: The Middle Ground

Mailu is younger than Mailcow but approaches the same problem with a more opinionated architecture. Same core components (Postfix, Dovecot, Rspamd) but organized as a cohesive unit with a more streamlined setup process. The admin UI is simpler and less overwhelming. The configuration is done via a single mailu.env file.

Who it’s for: Someone who wants Mailcow’s capabilities with less moving parts and a gentler learning curve. Mailu’s setup.mailu.io wizard generates your entire Compose config and env file in a browser. You answer questions, download the file, and run it.

docker-compose.yml
# Generated by https://setup.mailu.io — example excerpt.
# Full setup: visit setup.mailu.io, fill in your domain/config, download.
services:
front:
image: ghcr.io/mailu/nginx:2024.06
restart: always
ports:
- "25:25"
- "465:465"
- "587:587"
- "993:993"
volumes:
- "/mailu/certs:/certs"
- "/mailu/overrides/nginx:/overrides:ro"
imap:
image: ghcr.io/mailu/dovecot:2024.06
restart: always
volumes:
- "/mailu/mail:/mail"
- "/mailu/overrides/dovecot:/overrides:ro"
smtp:
image: ghcr.io/mailu/postfix:2024.06
restart: always
volumes:
- "/mailu/mailqueue:/queue"
antispam:
image: ghcr.io/mailu/rspamd:2024.06
restart: always
webmail:
image: ghcr.io/mailu/rainloop:2024.06
restart: always

Mailu uses Rainloop or Roundcube for webmail — functional but not as polished as SOGo. The tradeoff is resource usage: Mailu typically runs lighter than Mailcow, making it viable on a 2 GB RAM VPS if you’re careful.

Mailu’s Kubernetes helm chart is also decent, which matters if you’re already running k3s. Mailcow on Kubernetes is possible but officially unsupported and a miserable experience.

The catch: Mailu’s upgrade path has occasionally been bumpy. The project has had some turbulence around its release cadence and Docker image hosting (it moved from Docker Hub to GHCR). Always pin to a specific version tag, not latest.

Verdict: Solid choice for personal use or a small family domain. Easier to set up than Mailcow, lighter on resources, gets you 90% of the way there.


Stalwart: The New Kid Written in Rust

Stalwart is different. It’s a single binary. It’s written in Rust. It supports SMTP, IMAP, JMAP, and ManageSieve out of the box — no assembly required, no fifteen containers talking to each other over a bridge network. It has its own spam filtering engine, its own DKIM signing, its own TLS management. The web admin UI was added in recent releases and is surprisingly complete.

Who it’s for: Fresh setups where you want simplicity and are willing to accept a younger project. JMAP support is a genuine differentiator — if you’re writing a client or using a JMAP-capable app, Stalwart is the only self-hosted option that gives you that natively.

docker-compose.yml
services:
stalwart:
image: stalwartlabs/mail-server:latest
restart: always
ports:
- "25:25"
- "465:465"
- "587:587"
- "993:993"
- "143:143"
- "4190:4190" # ManageSieve
- "8080:8080" # Admin UI
volumes:
- stalwart-data:/opt/stalwart-mail
environment:
- TZ=UTC
volumes:
stalwart-data:

That’s it. One service. One volume. Stalwart generates its own config on first run, walks you through setup via the web UI, and handles Let’s Encrypt certificates automatically. Compared to Mailcow’s 15-container orchestra, it’s almost suspicious how simple it is.

Resource usage: Stalwart runs happily on 1 GB RAM. You could run it on a $4/month VPS and have headroom left over.

The catch: Stalwart is newer. The community is smaller. If you hit a weird edge case, you’re more likely to end up reading source code than finding a Stack Overflow answer. Some enterprise features (clustering, certain auth backends) are in the paid tier. The spam filtering is capable but not as battle-tested as Rspamd. If you’re migrating from an existing setup with years of Rspamd training data, you’ll feel that gap.

Verdict: Best choice for fresh setups, personal use, or anyone who finds Mailcow’s complexity exhausting. Watch the project’s maturity before deploying it for a 50-person org.


DNS Records That Actually Matter

All three stacks need the same DNS setup. Get this wrong and it doesn’t matter which server you chose.

dns-records.txt
# Replace mail.yourdomain.com and yourdomain.com with your actual values.
# Replace YOUR_SERVER_IP with your VPS IP.
# Replace YOUR_DKIM_PUBLIC_KEY with the key your mail server generated.
# MX Record — tells the world where to deliver your mail
yourdomain.com. IN MX 10 mail.yourdomain.com.
# A Record — your mail server's IP
mail.yourdomain.com. IN A YOUR_SERVER_IP
# PTR Record — set in your VPS control panel (reverse DNS)
# YOUR_SERVER_IP -> mail.yourdomain.com
# SPF — authorize your mail server to send for your domain
yourdomain.com. IN TXT "v=spf1 mx ~all"
# DKIM — paste the public key your mail server generated
# Mailcow: Admin > Configuration > ARC/DKIM keys
# Mailu: Admin > Mail domains > Details > DKIM Key
# Stalwart: Settings > DKIM > Generate
dkim._domainkey.yourdomain.com. IN TXT "v=DKIM1; k=rsa; p=YOUR_DKIM_PUBLIC_KEY"
# DMARC — tell receivers what to do with failures (start with none, tighten later)
_dmarc.yourdomain.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com"
# MTA-STS + TLS-RPT (increasingly required, especially for Gmail)
_mta-sts.yourdomain.com. IN TXT "v=STSv1; id=20260524"
_smtp._tls.yourdomain.com. IN TXT "v=TLSRPTv1; rua=mailto:tls-rpt@yourdomain.com"

After setting these records, verify with:

Terminal window
# Check SPF
dig TXT yourdomain.com +short
# Check DKIM
dig TXT dkim._domainkey.yourdomain.com +short
# Check DMARC
dig TXT _dmarc.yourdomain.com +short
# Verify port 25 is reachable from your server
telnet smtp.gmail.com 25
# Test your full sending reputation
# Use mail-tester.com or MXToolbox deliverability check
curl -s "https://check.spamhaus.org/listed/?searchterm=YOUR_SERVER_IP"

Once you’re satisfied with local DNS, run your domain through mail-tester.com by sending it a test email. Score under 8? Fix what it tells you before you send anything real.


The Decision Matrix

Here’s the quick version:

Pick Mailcow if: You want the most mature option, need shared calendars (CalDAV/CardDAV), are running email for a small team, and have a VPS with at least 4 GB RAM. The UI is the best of the three.

Pick Mailu if: You want Mailcow’s feature set with a lighter footprint and a simpler initial setup. Good for personal use or a family domain. Works well on Kubernetes if that’s your environment.

Pick Stalwart if: You’re starting fresh, value simplicity, want JMAP support, or just don’t want to babysit fifteen containers. Best choice for 2026 new deployments. Watch it mature before betting a company on it.

Pick none of them and use Migadu if: You tried one of the above and your emails to Gmail still go to spam after two weeks of troubleshooting. Migadu is $19/year for unlimited domains and addresses, it has real deliverability because they manage the IP reputation, and your time is worth more than the $19. Fastmail is another solid option at $50/year if you want a polished client.


The Escape Hatch

Here’s the honest truth: the single biggest factor in whether your self-hosted email works is not which software you chose. It’s whether your IP is clean, your DNS is correct, and your sending volume is sane.

If you’re on a residential connection: don’t. Get a VPS.

If you’re on AWS/GCP/Azure/DigitalOcean: don’t. Their IPs are tarpitted everywhere. Get a Hetzner CX22 for €4/month, verify port 25 is open, and set your PTR record in the Hetzner Cloud console before you do anything else.

If you’ve done all that and your emails still bounce after three weeks: pay Migadu. You haven’t failed. You’ve correctly diagnosed that deliverability reputation is a long-term asset that costs real money to maintain, and you’ve chosen to rent someone else’s reputation instead of building your own. That’s a reasonable engineering decision.

But if you want the ownership, the control, and the quiet satisfaction of watching your own SMTP server relay mail to Gmail without incident — now you know which three stacks are worth your time.

Start with Stalwart. Blame the DNS first. Always.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it'll show up above once verified.


Previous Post
Beyond Akismet: Spam Protection for 2026
Next Post
Authentik vs Authelia: SSO for Your Self-Hosted Stack

Discussion

Powered by Garrul . Sign in with GitHub or Google, or post anonymously.

Related Posts