Last October a friend who runs a four-person legal consultancy in Boca lost access to his Microsoft 365 admin panel for three days over a billing dispute with a reseller. He could receive mail but not send. The client who needed discovery documents by close of business Friday got radio silence. He called me Sunday night asking if Cloudflare could “just handle MX records for now.” I explained that Cloudflare does not run mail servers, that MX records point to something you still have to actually operate, and that his problem was not DNS. Then I spent Monday morning migrating him to Migadu while his admin panel came back to life. That day reminded me that self-hosting email in 2026 is a choice that most people should not make, but that for a specific small set of use cases, the math still works if you walk in with open eyes. I run Mailcow on a dedicated Hetzner VPS for my family and a handful of project domains. I tested Mail-in-a-Box for six months in 2024 before switching back. This article is the comparison I wish I had read before that first deployment.
Why most people should not self-host email in 2026
The deliverability cliff is real. If you spin up a VPS with a fresh IP and send your first message to a Gmail address, there is a non-trivial chance that message lands in spam or gets silently rejected with a 550 response. Google and Microsoft maintain internal IP reputation databases that penalize addresses with no sending history. You will spend the first two weeks carefully warming up your IP by sending small batches to domains that do not immediately blocklist you, gradually increasing volume, and praying that nobody on your list marks you as spam. I have done this twice. It is soul-crushing and not a weekend project.
Getting off a blocklist is worse. Spamhaus, Barracuda, Microsoft SNDS, the half-dozen services that feed into Gmail’s internal reputation engine. If your IP was previously used by a spammer (common on budget VPS providers), you inherit that reputation. Some blocklists offer automated removal after 24 hours. Some require a manual request with proof of ownership. One blocklist I encountered required a manual request form and a 48-hour wait before delisting. Another sent an automated email instructing me to verify domain ownership via TXT record before they would process the request.
The alternatives are actually fine. Migadu costs $19 per year for ten mailboxes and unlimited domains. Fastmail is $50 per year per user with calendar and contact sync that works. ProtonMail exists if you need zero-knowledge encryption and are willing to accept the limitations of that model. Microsoft 365 Business Basic is $6 per user per month and includes a terabyte of OneDrive storage that you will never use. For most small teams, paying one of these services is the correct decision. You get deliverability that works, spam filtering that adapts, and the ability to call someone when things break. You lose the ability to grep your mail spool and the satisfaction of typing doveadm commands, but most people are okay with that trade.
Who should self-host email anyway
I self-host for three reasons. First, I want to own my mail archive. Twenty years of correspondence lives in Maildir format on a ZFS pool that I back up to Backblaze B2 with restic on a daily schedule. No vendor can lock me out of that archive, change the terms of service, or silently scan it for advertising signals. Second, I run a dozen project domains and want unlimited aliases without paying per-address fees. receipts@example.com, newsletters@example.com, linkedin@example.com, all routing to the same inbox but filterable and disposable. Third, I enjoy the hobby. I am the kind of person who labels USB drives. Make of that what you will.
Small teams with strict data residency requirements sometimes have no choice. A law firm in Germany that cannot legally send client mail through US-based servers, a medical practice that interprets HIPAA to mean “we run our own MX,” a nonprofit that wants to prove to donors that their correspondence is not monetized. These are edge cases but they exist. If you are in one of these buckets and you have someone on staff who knows what postconf does, self-hosting might be the right answer.
Families running a homelab can self-host email as a learning project with the understanding that you will need a commercial backup. I ran Mailcow for my household for 18 months before I was confident enough to turn off the Gmail forwarding rule. My wife still has a Fastmail account that she checks once a week because she does not entirely trust my uptime. That is reasonable.
Mailcow architecture as of April 2026
Mailcow is a Docker Compose stack that bundles Postfix, Dovecot, Rspamd, SOGo (groupware), ClamAV, Solr (full-text search), Redis, MariaDB, and an Nginx reverse proxy into a single docker-compose.yml that you clone from GitHub. The project is maintained by a small German team and has been stable since 2017. As of this writing, the current stable release continues the pattern of quarterly updates with incremental improvements to Rspamd filtering and the SOGo webmail interface.
The modular Docker architecture means you can disable components you do not need. I turn off ClamAV because virus scanning on a personal mail server is theater (Rspamd already catches phishing and malware links). I leave Solr enabled because full-text search across 60,000 messages is worth the extra 512 MB of RAM. The web UI is React-based, loads quickly, and lets you add mailboxes or view logs without hunting through submenus. That said, I still ssh into the box twice a week because something always needs a manual docker compose restart after an Ubuntu kernel update.
Upgrades are a git pull followed by docker compose pull and docker compose up -d. The Mailcow team stages breaking changes carefully and documents them in a changelog that you actually need to read. I have upgraded through six minor releases without data loss. Once I missed a pre-upgrade database migration step and spent an evening restoring from backup. That was my fault.
The Docker-everything pattern is both a strength and a weakness. Strength because you can replicate the stack on a new host in under an hour. Weakness because debugging a Postfix issue requires you to docker exec into the Postfix container, find the config file, remember that changes inside the container are ephemeral, and then figure out which bind-mounted config override directory Mailcow actually uses. The official documentation is comprehensive but assumes you understand how Docker Compose networks and volumes work.
Mail-in-a-Box architecture: the opinionated single-box approach
Mail-in-a-Box (MiaB) is a single bash script that installs and configures Postfix, Dovecot, Roundcube, Nextcloud (for contacts and calendar), and a custom Python-based admin panel on a fresh Ubuntu 22.04 LTS server. You run the script, answer three questions, and twenty minutes later you have a working mail server. The project homepage is at mailinabox.email and the philosophy is that one script does it all.
MiaB is less flexible than Mailcow. You cannot disable ClamAV. You cannot swap Roundcube for SOGo. You cannot run it in Docker (there are unofficial Docker ports but they are not supported). You install it on a dedicated box that does nothing else. The box must have a public IP, reverse DNS that matches your hostname, and ports 25, 587, 993, 443, and 80 open. If you want to run a second service on the same box, you are fighting the MiaB nginx config and the custom firewall rules that the script generates.
The upside is simplicity. The admin panel shows you your DKIM keys, your SPF record, your DMARC policy, and a checklist of things that might be misconfigured. It automatically renews Let’s Encrypt certificates. It runs a nightly backup script that writes encrypted tarballs to /home/user-data/backup and can push them to S3-compatible storage. It is the mail server for people who do not want to become mail server experts.
I ran MiaB on a Hetzner CX21 for six months in 2024. The initial install took about thirty minutes. Updates came via the same curl script, followed by a reboot. Deliverability was fine once I got through the IP warm-up period. I switched back to Mailcow because I wanted SOGo’s ActiveSync support for my phone, because I wanted to disable ClamAV, and because I found the MiaB Nextcloud bundle to be half-baked. (Nextcloud is a full application suite. Bolting it onto a mail server as an afterthought produces a Nextcloud instance that nobody wants to use and a mail server that carries extra weight.)
Deliverability the hard way: SPF, DKIM, DMARC, and the reputation treadmill
You need four DNS records to send mail in 2026. SPF is a TXT record that says “these IPs are allowed to send mail for this domain.” DKIM is a public key that your mail server signs every outbound message with. DMARC is a policy that tells receiving servers what to do if SPF or DKIM fails. MTA-STS is a newer standard (RFC 8461) that pins your MX records and forces TLS. Both Mailcow and MiaB configure these automatically but you still need to copy the generated TXT records into your DNS zone.
BIMI (Brand Indicators for Message Identification) is the thing where your logo appears next to your mail in Gmail. It requires a verified DMARC policy, a hosted SVG logo, and optionally a Verified Mark Certificate that costs several thousand dollars per year. I have not bothered. BIMI is cosmetic and primarily benefits large senders who care about brand visibility in the inbox.
PTR records (reverse DNS) are non-negotiable. Your VPS provider must set the PTR record for your IP to match your mail server’s hostname. Most providers let you configure this in their control panel. Hetzner does. If your PTR does not match, Yahoo and AOL (yes, people still use AOL) will reject your mail with a 550 error. I learned this in 2019 and I am still annoyed about it.
The IP reputation reality check: even with perfect DNS records, a fresh IP has zero reputation. You will send your first 100 messages and watch half of them get flagged as spam. You will visit mail-tester.com and get a score of 7/10 because your IP is “not well known.” You will send a test message to your Gmail account and find it in the Spam folder with the explanation “this message is similar to messages that were detected by our spam filters.” There is no shortcut. You send carefully, you monitor your logs, and you wait for the reputation algorithms to notice that you are not a spammer.
The warm-up period for a fresh IP (and why I keep a Migadu account for the first month)
Here is how I warm up a new mail server. Day one: I send five test messages to my personal Gmail, Outlook, and Fastmail accounts. I check that SPF, DKIM, and DMARC all pass. I verify that the messages land in the inbox and not in spam. Day two: I send twenty messages to a mix of personal and business addresses. Day three: fifty messages. Day seven: two hundred messages. I do not send bulk mail (newsletters, automated notifications) for the first two weeks. I do not send to distribution lists. I send person-to-person replies and new threads that look like legitimate correspondence.
During this period I keep a Migadu account active and configured as a secondary outbound relay in my mail client. If I need to send something urgent to a domain that I suspect will blocklist me (a client using Microsoft 365 with aggressive filtering, a university with a poorly configured spam appliance), I route that message through Migadu. This is not cheating. This is acknowledging that IP reputation is a thing you cannot instantly buy.
Mailcow logs everything to /var/lib/docker/volumes/mailcowdockerized_rspamd-vol-1/_data/rspamd.log (the exact volume name will vary based on your Mailcow installation path). I tail that log and watch for DMARC alignment failures, SPF softfails, and greylisting delays. Greylisting (where a receiving server temporarily rejects your message and asks you to retry in five minutes) is normal and not a sign of a problem. A 550 permanent reject with “listed in zen.spamhaus.org” is a problem.
After four weeks of gradual sending, my IP typically has enough reputation to send to Gmail and Outlook without landing in spam. Yahoo remains unpredictable. ProtonMail and Tutanota accept everything because they do not run aggressive reputation filters (they rely on user reporting and content heuristics instead). Mailchimp and SendGrid domains occasionally reject me for no documented reason, and I have stopped caring.
Backup MX strategies that actually work in 2026
A backup MX is a secondary mail server that accepts mail when your primary is down. In theory it is a simple failover mechanism. In practice it is a spam magnet because spammers send to your backup MX knowing that many backup servers have weaker filtering. Both Mailcow and MiaB can act as a backup MX for another domain but I do not recommend this unless you run two geographically separate instances behind a load balancer. That is more complexity than most self-hosters want.
I use Migadu as my backup MX. I pay $19 per year for a Migadu account, configure my domain’s MX records to list mx1.migadu.com and mx2.migadu.com with higher priority (lower number) than my Mailcow server, and set Migadu to relay all inbound mail to my Mailcow IP. If my Mailcow server is down, Migadu queues the messages and retries every 15 minutes until my server comes back. If my server is down for more than four hours, the messages stay in Migadu’s queue for up to five days and I can retrieve them via IMAP if I need to read something urgently.
MXroute offers a similar service. You configure your domain in their control panel, point your MX records at their servers, and they relay everything to your self-hosted server. This works but MXroute does not offer a web interface to view queued messages, so if your server is down long enough that messages start bouncing, you lose them. Migadu gives you an IMAP mailbox as a safety net.
The Hetzner backup MX trick from 2018 (running a minimal Postfix relay on a separate Hetzner VPS in a different datacenter) is no longer worth the effort. Hetzner now blocks outbound port 25 on new accounts by default and you have to request an unlock, which can take 24 hours. By the time you have set up the relay, configured firewall rules, and tested failover, you could have just paid for a Migadu account and been done.
Cost reality: Hetzner VPS vs ProtonMail vs Migadu over three years for five users
Hetzner CX31 (as of April 2026: 4 vCPU, 8 GB RAM, 80 GB NVMe, dedicated IPv4 with reverse DNS): approximately €10 per month based on current pricing. Over three years that is €360, or roughly $390 at April 2026 exchange rates. Add €5 per month for a weekly snapshot backup (optional but recommended) and you are at €540 over three years ($585).
ProtonMail Business (current pricing as of this writing, subject to change): Business plans typically start at higher user minimums and cost significantly more than self-hosting. If you are evaluating ProtonMail, verify current pricing and user minimums on their website, as these change frequently. Over three years, expect to pay several thousand dollars for a small team. You get calendar, contacts, and VPN included. You also get zero-knowledge encryption and the inability to use standard IMAP clients without their bridge software.
Migadu Micro ($19 per year, unlimited domains, ten mailboxes): $57 over three years. This is the correct answer for most people and I recommend it without reservation. You do not get groupware (calendar and contacts) but you can run a separate NextCloud instance on a homelab mini PC if you want that.
Microsoft 365 Business Basic ($6 per user per month): $360 per year for five users, $1,080 over three years. You get Outlook on the web, a terabyte of OneDrive, Teams, and the knowledge that Microsoft will never go out of business and take your mail with them.
My total cost for self-hosting: Hetzner CX31 at roughly €10/month plus Migadu as backup MX at $19/year. Over three years that is €360 + $57 = approximately $447. I spend roughly 10 hours per year maintaining the server (applying Ubuntu updates, upgrading Mailcow, investigating why spam filtering suddenly got worse after an Rspamd version bump, restoring from backup that one time I broke the MariaDB container). If I value my time at $50 per hour, the real cost is closer to $947 over three years. That is still cheaper than ProtonMail but more expensive than Migadu. The math works for me because I enjoy the hobby and because I want the control. It probably does not work for you.
My setup today: Mailcow on Hetzner, Migadu as backup MX, and the parts I would change
I run the current stable Mailcow release on a Hetzner CX31 in the Falkenstein datacenter (Germany). The server handles mail for my family domain, two consulting project domains, and a handful of throwaway test domains. I have 12 active mailboxes and roughly 400 aliases routing to those boxes. SOGo provides calendar and contact sync via CalDAV and CardDAV. I use Fastmail’s iOS calendar and contacts apps as clients (they work with any CalDAV/CardDAV server, not just Fastmail). My phone syncs mail via IMAP IDLE. Desktop clients are Thunderbird on Linux and Mail.app on my wife’s Mac.
Migadu is configured as a backup MX with higher-priority MX records. If my Mailcow server goes down, Migadu queues inbound mail and I can retrieve it via IMAP if needed. In 18 months this has happened once (a bad Ubuntu kernel update that broke Docker networking and I did not notice for six hours because it was a Saturday).
I back up the Mailcow data directory daily to Backblaze B2 using a restic script that runs at 03:00 UTC. The Mailcow installation itself is disposable (I can redeploy it in under an hour). The data directory contains the MariaDB database, the mail spool in Maildir format, the DKIM keys, the Redis AOF files, and the SOGo PostgreSQL database. That is what I need to restore if the server burns down. I test the backup every six months by restoring to a local VM. It works.
Things I would do differently if I were starting over: I would skip ClamAV from the beginning. I would allocate 16 GB of RAM instead of 8 GB (the CX31 is fine but the CX41 would give me more headroom for Solr and MariaDB caching). I would document my DNS records in a git repository with a commit message explaining why each record exists, because I spent 45 minutes last November trying to remember why I had a second DKIM selector. I would set up monitoring with Uptime Kuma or a similar tool that sends me a push notification when the mail server stops responding on port 25 (I currently rely on Migadu queuing messages and my wife telling me that mail is slow).
Which one should you actually run
If you want a mail server that you can deploy in one evening and mostly forget about, and you are willing to live with the constraint that the server does nothing else, use Mail-in-a-Box. It is opinionated, it handles the DNS records for you, and the upgrade path is stable. You will need to read the documentation when you want to do something unusual but for basic “I want my own MX and I want aliases and I want Roundcube” use cases it is the correct tool.
If you want modularity, if you want to run the mail server in Docker alongside other services, if you want SOGo instead of Roundcube, if you want to disable ClamAV and save 300 MB of RAM, use Mailcow. You will spend more time learning the system. You will find yourself running docker exec -it mailcowdockerized-postfix-mailcow-1 /bin/bash and poking around /etc/postfix more often than you expected. You will read the Mailcow documentation and the Postfix documentation and occasionally the Dovecot documentation when something breaks in a way that the web UI cannot fix. The payoff is that you understand how the system works and you can bend it to your needs.
If you are not sure which one you want, start with Mail-in-a-Box. Run it for six months. If you find yourself frustrated by the lack of flexibility, migrate to Mailcow. If you find yourself wishing the system were simpler, stay with MiaB or switch to Migadu and stop self-hosting. There is no shame in deciding that the correct answer is to pay someone else $19 per year to handle this problem. I self-host because I have spent enough hours on this that the sunk cost has become an asset (I can debug Postfix TLS negotiation failures without opening the manual now) and because I genuinely enjoy the control. Most people should not make that trade.
Both projects are well-maintained, both have active communities, and both work. The question is which set of trade-offs you can live with. I chose Mailcow. You might choose differently, and as long as you walk in knowing that self-hosted email is a five-evening commitment per year and not a Sunday afternoon project, you will be fine.