NitroMTA
github.com/nitrosend/nitromta- Category
- Developer Tools
- Rank
- No. 1271Tools index
- Pricing
- Open Source
- Type
- TOOL
- GitHub
- 125 stars
- Latest release
- v0.3.0
- Date
About
NitroMTA is an open-source mail delivery engine written in Rust that accepts Amazon SES v2 sending calls, so existing code only needs a new endpoint and credentials. It sends from IP addresses the operator controls, commits each submission to disk before accepting it, signs mail with DKIM, and warms new IPs gradually per receiving provider. The authors report higher throughput than KumoMTA and Postfix on their own benchmark and say it has run in production for a few weeks.
What it does
A self-hosted mail server that answers the Amazon SES v2 API, so an application written against SES switches over by changing its endpoint and access keys. Each message goes into a local SQLite store, the sender gets an answer only after that write is synced to disk, and the engine then delivers straight to recipients' mail servers from the operator's own addresses. It signs with DKIM, requires TLS by default, and paces each new address per receiving provider starting at 50 messages a day. A capture mode runs the whole engine locally and shows messages in a browser instead of sending them.
Why it's ranked here
The case rests on how much of the operating contract is written down. The durability guide lists each failure and what survives it, including the duplicate-delivery window SMTP itself cannot close. The compatibility guide names every supported SES operation and refuses unsupported fields by name rather than ignoring them, and the official JavaScript, Python and Ruby SDKs run against the engine in its own checks. It is Apache 2.0 licensed, with signed build provenance on every package. The ceiling is architectural: one host, no replication, so it suits teams prepared to own a single mail server.
What's good
Failure handling is specific. A submission is acknowledged only once committed, a crash mid-attempt is recovered and retried, and every uncertain delivery is counted so the at-least-once window shows up in metrics. Testing goes past unit tests: simulated power loss at every disk operation, a release binary killed mid-send with none of roughly 4,960 acknowledged recipients lost or sent twice, and a store moved to a fresh host and delivered from there. A doctor command checks reverse DNS, SPF, DKIM, DMARC and port 25 and prints the exact record to publish. Unsafe Rust is denied across the workspace.
Tradeoffs
Everything lives on one host's disk: no replication, no failover, and losing the disk loses whatever was accepted since the last backup. Open and click tracking are absent, Easy DKIM and single-address identities are refused, and several SES event fields are left out. Templates support plain substitution only, so ones with blocks, partials or comments are rejected. No request is idempotent, so a send retried after a lost answer goes out twice, as with SES. The speed comparison against KumoMTA and Postfix comes from the authors' own harness. The install guide warns that minor releases before 1.0 may change configuration keys and commands.
How to use it well
Fits a team already sending through SES that wants its own IPs and can run a Linux mail host with port 25 open, reverse DNS and a return path domain. Start in capture mode to confirm existing SDK calls work unchanged, then shift traffic gradually, keeping most mail on SES while warmup raises each new address's caps. Run a local DNSSEC-validating resolver if DANE matters, and store the keys and configuration off the host, since backups cannot be restored without them. Teams that need multi-region redundancy or open and click tracking should look elsewhere.
Technical notes+
Cargo.toml declares a Rust 2024 workspace (crates/*, bench/*, fuzz, xtask) whose workspace lints deny unsafe_code, dbg_macro, todo and unimplemented, and patches the hickory DNS crates to a pinned git revision until an upstream release lands. crates/engine/src/main.rs is a thin entry that calls engine::main with default Hooks. crates/engine-smtp/src/lib.rs describes sans-I/O state machines for submission, delivery, routing, MTA-STS and DANE, so the same code runs over sockets and in the simulator. crates/engine-store/src/lib.rs keeps every authoritative record in one SQLite database behind a single commit owner that groups synchronous commits, with a keys module sealing stored secrets. docs/durability.md covers WAL mode, the failure table, fenced restore and the advisory disk reserve; docs/compatibility.md lists the served SES and SNS operations and each divergence from SES.
Observed
- License
- Apache-2.0
- Language
- Rust, with unsafe code denied workspace-wide
- Storage
- One SQLite database in write-ahead logging mode, every commit synced
- Interfaces
- SES v2 HTTPS API, SNS subset, SMTP submission, CLI and admin socket
- Packaging
- Debian and RPM packages, AUR, container image, Homebrew, Linux archives
- Platform
- Linux with systemd on x86_64 or arm64
- Deployment model
- Single host, no replication or failover
- Delivery guarantee
- At least once; uncertain attempts are counted
- SDK testing
- Official SES v2 SDKs for JavaScript, Python and Ruby run against the engine
- Not supported
- Open and click tracking, Easy DKIM, email address identities
Read from README.md, Cargo.toml, crates/engine/src/main.rs, crates/engine-smtp/src/lib.rs, crates/engine-store/src/lib.rs, docs/durability.md, docs/compatibility.md, docs/install.md, docs/migrate-from-ses.md, LICENSE.
Tags
Tech Stack
Comments (0)
No comments yet
Editorially curated, with community endorsements as a secondary signal. Corrections welcome.