Stalwart
One Rust binary that is SMTP, IMAP, JMAP, CalDAV and CardDAV at the same time
Stalwart is an all-in-one mail and collaboration server written in Rust, covering SMTP, IMAP4, POP3, JMAP, CalDAV, CardDAV and WebDAV in a single process. It replaces a Postfix plus Dovecot plus Rspamd stack, or a hosted mailbox, with one binary and one datastore.
Our verdict on Stalwart#
Everything true about mailcow's deliverability risk is true here. Most residential ISPs and several clouds block outbound port 25, you cannot set a PTR record for an address you do not own, and a new IP has no reputation, so expect Gmail and Outlook to greylist or reject you for weeks. Stalwart does not fix that and no software can. What it fixes is the stack: one Rust binary replacing Postfix, Dovecot, Rspamd and a WebDAV server, with RocksDB on local disk as the default store for messages, blobs, index and cache alike. The license is dual. Community is AGPL-3.0 and free self-hosted use is unrestricted, including commercially, but the same binary contains Enterprise code that a key unlocks. Check the split before you design around a feature: multi-tenancy, account un-deletion, restoring deleted mail, SCIM provisioning, delivery history, the AI spam classifier and third-party OIDC login are all paid. Still 0.16.x in September 2026, with weekly releases.
Who Stalwart is for#
Choose it if
- You have a clean static IP with controllable reverse DNS and want a mail server whose configuration you can read in one sitting.
- Small deployments where 18 containers are absurd and a single process in a few hundred megabytes is not.
- Anyone who wants JMAP, or wants CalDAV and CardDAV from the same server as their mail rather than bolting on Radicale.
- Operators relaying outbound through a reputable SMTP provider while self-hosting receipt, filtering and storage.
Look elsewhere if
- Your provider blocks port 25 or will not set a PTR record matching your mail hostname. That is a hard stop for outbound mail.
- You need multi-tenancy, deleted-mail recovery, SCIM or login via Keycloak. Those are Enterprise, not Community, and no amount of configuration reaches them.
- You want a stable API and a long track record. It is pre-1.0, ships roughly weekly, and 0.15 to 0.16 needed documented migration steps rather than a straight binary swap.
What running it actually looks like#
One container and two volumes: /etc/stalwart for configuration and /var/lib/stalwart for data. Publish 25, 587, 465, 143, 993, 110, 995, 4190, 443 and 8080. The first start runs a bootstrap that generates a temporary administrator account with a random 16-character password and writes it to the container's standard error exactly once, so capture it from docker logs before doing anything else. Finish setup in the web admin on 8080, then close that port. By default structured data, blobs, full-text index and cache all live in RocksDB on local disk, which is the recommended single-node shape; PostgreSQL, MySQL, S3 and FoundationDB are options you probably do not need. Upgrades inside 0.16.x are a pull and restart; coming from 0.15 or earlier, read the upgrade doc first.
Resource profile#
- Memory
- 150 MB idle, around 512 MB in ordinary use. Estimated from small single-domain installs, not a documented minimum. One Rust process with no JVM and no separate spam daemon; RocksDB's block cache and the full-text index account for most of the growth.
- CPU and acceleration
- Near idle at rest. Spam filtering, DKIM signing and DMARC reporting all run in-process, so an inbound burst spikes one core, and indexing a freshly imported mailbox is the heaviest thing it does.
- Storage growth
- RocksDB keeps messages, blobs, index and accounts together under `/var/lib/stalwart`, so mail volume plus index is the whole story. There is no separate maildir tree to size on its own.
- Operational load
- 3 of 5, Moderate. One container, one data directory, and upgrades inside 0.16.x are a `docker pull`. It scores 3 rather than 1 because it is still pre-1.0 with documented migration steps between minor lines, and because it is a mail server, which carries DNS and reputation work that never finishes.
Figures describe a small single-household install and are the working assumptions behind our stack planner. Your numbers will differ with library size, user count and hardware. See methodology.
Data and backup surface#
Back up /etc/stalwart, which holds configuration, TLS material and the DKIM private keys, and /var/lib/stalwart, which holds the RocksDB store with messages, blobs, index and accounts. Losing DKIM keys is not fatal but every message signed with the old selector fails verification until you publish new DNS. RocksDB is a live log-structured store, so copying the directory under a running server can capture a torn state: stop the container or take a filesystem snapshot. If you moved blobs to S3 or the store to PostgreSQL, back those up on their own terms and the local directory shrinks to config. The full-text index is regenerable, but rebuilding it over a large mailbox is slow enough that keeping it is worth the bytes.
Derived backup shape
Embedded key-value store. Stop the service and copy its data directory, or use the project's own export command. There is no dump utility to run against it while it is live.
Traps and surprises#
The bootstrap admin password is printed once
On a fresh start Stalwart creates a fallback administrator with a random 16-character password and writes it only to the container's stderr. If you started with docker compose up -d and never looked at the logs, or your logging driver rotated it away, you cannot log in to finish setup. Read docker logs immediately after the first start, or set the fallback administrator credentials explicitly in the configuration beforehand.
Third-party OIDC login is an Enterprise feature
Stalwart Community can act as an OAuth 2.0 and OpenID Connect provider, and it authenticates against its internal directory, LDAP, Active Directory or SQL. What it will not do without an Enterprise license is accept logins from an external OIDC provider such as Keycloak, Authentik or Entra ID. If your plan was to put every self-hosted service behind one identity provider, mail is the one that will not join for free.
RocksDB does not tolerate being copied live
The default store is a single RocksDB instance holding messages, blobs and index together. Rsyncing /var/lib/stalwart while the server runs can produce a copy with a partially written write-ahead log that fails to open, and you will not find out until you try to restore. Stop the container for the copy, take an LVM or ZFS snapshot, or move the store to PostgreSQL and dump it properly.
0.15 to 0.16 is not a drop-in upgrade
Point releases inside 0.16.x are a docker pull and restart, but crossing a minor line has documented migration steps that the release notes point at explicitly. Because the project ships roughly weekly, it is easy to fall several minors behind and then jump. Upgrade one minor line at a time, read the upgrade page for each, and snapshot the data volume first because there is no downgrade path.
Port 8080 stays open unless you close it
The management interface is exposed on 8080 for initial setup and is not automatically disabled afterwards. Leaving it published means an unauthenticated-looking admin surface on the public internet, protected only by your admin password. Once setup is done, either stop publishing 8080 in the compose file or bind it to localhost and reach it through an SSH tunnel or your reverse proxy with its own access control.
Specifications#
- Category
- Chat, mail and notifications
- Licence
- AGPL-3.0 for the Community edition, dual licensed with the proprietary Stalwart Enterprise License for gated features (Copyleft)
- Written in
- Rust
- First release
- 2023
- Maturity
- Young
- Datastore
- RocksDB by default; PostgreSQL, MySQL, SQLite, FoundationDB, S3 and Redis also supported
- Default ports
25,110,143,443,465,587,993,995,4190,8080- Ships as
- docker, native binary installer, kubernetes
- arm64 builds
- Yes
- Identity
- LDAP only. Community authenticates against an internal directory, LDAP/Active Directory or SQL; signing in through a third-party OIDC provider such as Keycloak or Authentik is an Enterprise feature.
- Replaces
- Google Workspace Gmail, Microsoft 365 Exchange Online, Zimbra, Fastmail
- Project site
- stalw.art
- Source
- github.com/stalwartlabs/stalwart
- Documentation
- stalw.art/docs/install
Alternatives to Stalwart#
Everything else in chat, mail and notifications, closest in operational weight first.
| Tool | Ops load | Idle RAM | Licence |
|---|---|---|---|
| Mattermost | 3, Moderate | 500 MB | AGPL-3.0 core, Mattermost Source Available License for `server/enterprise/`, Apache-2.0 for webapp and admin tools, MIT for official binaries |
| Synapse | 4, Heavy | 700 MB | AGPL-3.0-only (or a commercial license from Element) |
| mailcow: dockerized | 4, Heavy | 3500 MB | GPL-3.0 for mailcow's own code; bundled components keep their own licenses |
| Gotify | 1, Set and forget | 20 MB | MIT |
| ntfy | 1, Set and forget | 30 MB | Apache-2.0 (dual licensed with GPL-2.0) |
Where Stalwart comes up elsewhere#
Migration guides
Sources#
Facts on this page were checked against the project's own material. Where a number is our own estimate rather than a published figure, the text says so.
Published . Last reviewed . Found something out of date? Tell us and we will fix it and log the change.