Skip to content
NewA free test that shows whether your emails will reach the inbox.

Archived: self-hosted outbound mail design

Archived: this describes the original self-hosted outbound design. Amazon SES is now the production outbound provider; Sukhovei Mail still operates inbound SMTP and stored inboxes.

By Arin Prajapati, founder, 5 min read

On this page (6)

Archived on 15 October 2026. This article records Sukhovei Mail's original self-hosted outbound design. Amazon SES is now the production outbound provider. Sukhovei Mail still runs inbound SMTP, stored inboxes and the delivery control plane; the KumoMTA adapter remains available for self-hosting.

At the time this was written, there were two common ways to build an email product. You could put an API in front of a large sending service and resell its delivery, or you can run the servers that talk SMTP to the rest of the internet. The first was faster to launch. We initially chose the second; the remainder is kept as a historical engineering record, not a description of the current production outbound path.

What the mail path is

“The mail path” is every hop an email takes between your code and someone else's mailbox, in both directions. In the archived design, all of it ran on machines we operated:

Archived 2026 design: receiving on Sukhovei Mail SMTP, sending through KumoMTAReceivingSendingSender's serverconnects on port 25mx1, mx2our Rust SMTP serverChecksrecipient, SPF, DKIM, spamStored, then 250Postgres and raw .emlYour app or agentAPI, SMTP or MCPcorelimits, suppressions, MIMEKumoMTADKIM, IP pools, warmupRecipient's serverGmail, Outlook, ...delivery logsYour inboxes: API, wait, WebSocket, webhooks, IMAP
Historical diagram. Production outbound now uses Amazon SES; inbound SMTP remains on Sukhovei Mail.
  • Receiving is our own SMTP server, written in Rust. Your domain's MX records point at mx1.mailbay.dev and mx2.mailbay.dev.
  • Sending went through KumoMTA, an open source mail transfer agent, on IP addresses we controlled, signed with your domain's DKIM key.
  • There was no third-party relay between Sukhovei Mail and the recipient server.

Why own it

Receiving is the product. Sukhovei Mail exists for agents and apps that hold conversations over email, so inbound is not a webhook bolted onto a sending API. Owning the SMTP server lets us decide things that a relay decides for you:

  • Mail for an address that does not exist is refused during the SMTP conversation, with 550 5.1.1 No such mailbox here. We never accept a message and bounce it later, which is how servers end up sending backscatter to forged senders.
  • The 250 OK that tells the sender “delivered” is only sent after the message is committed to the database. A crash at the wrong moment means the sender retries, not that mail vanishes.
  • Catch-all addresses on a private subdomain per workspace, plus addressing, and a wait call that wakes the moment the commit lands are all decisions about how the server treats a recipient. We can only make them because we own the server.

Privacy was simpler to describe in that design. Outbound bodies did not pass through a relay provider. Today Amazon SES processes outbound mail and is listed on our subprocessors page; Sukhovei Mail continues to store message data.

The old debugging path. When a message was late, the answer was in our logs: the SMTP transcript, KumoMTA's queue and the remote server's reply, which we stored per recipient and showed as response, such as 550 5.1.1 no such user.

What it costs

We would rather say this plainly than have you find out:

  • New IPs have no reputation. Gmail, Microsoft and Yahoo trust a sending IP after weeks of steady, wanted mail from it. Until then they throttle it or file mail as spam. A relay provider has already paid that cost; we are paying it now while we grow carefully.
  • Hosting is constrained. We need providers that allow outbound port 25 and let us set reverse DNS on every IP. Many cloud providers block port 25 by default and only lift it on request.
  • No fallback. If one of our IPs is blocklisted, we cannot quietly fail over to someone else's network. We need several IPs per pool, monitoring and a delisting runbook instead.
  • It is more work. Queues, retries, bounce handling, TLS on port 25, DKIM key management and feedback loops are ours to run.

How we protect the IPs

Every customer shares the reputation of the IPs they send from, so most of our sending rules exist to keep one bad sender from hurting everyone else:

  • Three IP pools. Free plan mail, paid plan mail and our own mail (sign in codes, alerts) leave from different addresses, so a bad free account cannot touch paying customers' delivery.
  • A separate domain for free inboxes. Free addresses live under mailbay.email, not mailbay.dev, so abuse of free inboxes cannot drag down the domain our own mail comes from.
  • A sandbox until you verify a domain. Without a verified domain, mail from mailbay.email addresses can only reach your own team and our test addresses.
  • A slow start. New accounts send to at most 100 recipients a day for their first 7 days.
  • Suppressions. A hard bounce or a spam complaint adds the address to your suppression list, and later sends to it fail at once with recipient_suppressed.
  • Warmup per mailbox provider. KumoMTA shapes traffic per destination. On day one each IP sends Gmail at most 20 messages an hour, and Outlook.com 10:
infra/kumomta/shaping.toml (week 1)
["gmail.com"]
enable_tls = "Required"
connection_limit = 2
max_connection_rate = "10/min"
max_deliveries_per_connection = 20
max_message_rate = "20/h"

["outlook.com"]
connection_limit = 1
max_connection_rate = "5/min"
max_deliveries_per_connection = 10
max_message_rate = "10/h"

The rates go up week by week, over about six weeks, and only when bounce, complaint and deferral rates over the previous days say they should. Mail over the rate waits in the queue; it is not dropped.

The inbound side

Receiving well is mostly about saying no early and cheaply. Our SMTP server limits connections and commands per IP, refuses unknown recipients at RCPT TO, and caps messages at 25 MB. After the data arrives it checks SPF, DKIM and DMARC, and asks rspamd for a spam verdict: a reject is refused in the SMTP session, likely spam is stored with spam: true, the rest is stored as normal mail. The results ride along on every message as auth_results, so your code or agent can decide what to trust. How those three checks work is in SPF, DKIM and DMARC explained. The same code powers our free email deliverability test, which scores any message you send it.

Where the self-hosted design stood when archived

At the time, Sukhovei Mail's new sending IPs were warming up and access was reviewed while reputation developed. Production outbound has since moved to Amazon SES. The self-hosted KumoMTA adapter remains available for operators who deliberately choose it, but it is not Sukhovei Mail's production delivery path.

Arin Prajapati, founder of Sukhovei MailA software engineer in Mumbai who builds Sukhovei Mail's mail servers, API and site. More about Arin and why he built Sukhovei Mail.

Put Sukhovei Mail to work

Get inboxes, sending, your own domains and MCP in one workspace. The free plan includes 3 inboxes, 3,000 emails a month and 3 custom domains, with no card.