I&#x27;m Kam, co-founder and CTO of Nitrosend.<p>Email is our lifeblood, so we&#x27;ve been gradually moving our email sending onto bare-metal servers and IPs we control.<p>We wanted to make that move without rewriting the application code already calling Amazon SES. So we built NitroMTA, an open-source SES replacement in Rust. We kept our existing SES v2 sending calls and changed the endpoint and credentials to send through our own engine.<p>We&#x27;ve been running it in production for a few weeks, moving more mail over as we warm our IPs and build reputation with each mailbox provider.<p><i>Keep the SES integration</i><p>For an application using boto3, this is the client configuration:<p><pre><code> import boto3 ses = boto3.client( &quot;sesv2&quot;, region_name=&quot;us-east-1&quot;, endpoint_url=&quot;https:&#x2F;&#x2F;mail.example.com&quot;, ) </code></pre> For the SES v2 sending operations we support, the existing calls keep working. We test the official JavaScript, Python and Ruby SDKs against the engine, along with Nodemailer and django-ses. The compatibility page lists the operations and differences from SES: <a href="https:&#x2F;&#x2F;nitromta.com&#x2F;docs&#x2F;compatibility&#x2F;" rel="nofollow">https:&#x2F;&#x2F;nitromta.com&#x2F;docs&#x2F;compatibility&#x2F;</a><p><i>Measuring against KumoMTA and Postfix</i><p>In our published 2 November comparison, NitroMTA sustained 3.16 times KumoMTA&#x27;s throughput and 4.11 times Postfix&#x27;s. These numbers measure SMTP submission and delivery.<p><pre><code> Engine Messages per second NitroMTA 3,313 KumoMTA 1,048 Postfix with OpenDKIM 806 </code></pre> Each engine had four CPU cores and 2 GiB of memory on the same AWS c7gd.metal bare-metal server, with its queue on local NVMe. The workload used 16 KiB messages, authenticated SMTP submission, TLS on submission and delivery, and RSA-2048 DKIM signing. Every engine committed a message to disk before acknowledging it.<p>The figures are medians of three interleaved runs per engine. The quick profile searches for the highest rate meeting its latency budgets using ten-second load steps, delivering to one receiver site with no added network delay. Across the nine runs, the harness sent 1.35 million messages and checked that each arrived once, with its body intact and its DKIM signature valid.<p>KumoMTA used its RocksDB spool with set_force_sync(true) to meet the same acceptance contract. KumoMTA documents that this forces database-wide flushes and can substantially reduce performance. The comparison is for that synchronous-acceptance contract; the harness also supports measuring its default asynchronous mode separately.<p>The method, configurations, exact versions and raw results are published, and you can run the comparison with cargo harness quick: <a href="https:&#x2F;&#x2F;nitromta.com&#x2F;docs&#x2F;benchmarks&#x2F;" rel="nofollow">https:&#x2F;&#x2F;nitromta.com&#x2F;docs&#x2F;benchmarks&#x2F;</a><p><i>Give each IP a budget for each provider</i><p>An IP needs a sending history with the receivers it sends to. We need to decide how much volume it gets today, what earns it more tomorrow, and what makes us back off.<p>We track the budget by sending IP and receiver group. That lets us hold an IP&#x27;s Gmail cap while increasing its cap elsewhere, or lower its Outlook.com cap when Microsoft&#x27;s responses call for it.<p>With warmup enabled, the shipped ladder starts at 50 messages a day. A day needs enough SMTP outcomes to test its cap before it earns an increase. Complaints, failures, deferrals and throttling can hold the cap or move it down a rung.<p>The Outlook.com defaults take fourteen clean daily increases to reach 10,000 messages a day. The default ladder takes seven. Both are configurable.<p>Before any of this, the host needs outbound port 25 and reverse DNS control for its sending addresses. The domains need SPF, DKIM and DMARC, and bounce and complaint reports need somewhere to arrive. We put the setup checks in nitromta doctor, which prints the missing records.<p>Provider feedback and durability details continue in a reply.

Comments are read-only. Visit Hacker News to participate in the discussion.