The seductive shortcut
If you set out to build an ESP today, the path of least resistance is obvious: build a control plane on top of Amazon SES, Postmark, or Resend. Your "Send" endpoint forwards the request, your customer-facing dashboard renders the events, and you charge a margin on volume. We've all seen this product. It's everywhere.
It's also fragile in ways that don't show up in the demo. The seams are invisible until they cut you.
What you actually buy when you wrap another ESP
You buy their deliverability decisions, but not their visibility into them. When Gmail starts deferring your customer's mail, you don't know which IP it came from, which (IP, domain, provider) tuple is reputation-damaged, or what the upstream's plan is. You're left tailing logs and writing apology emails.
You also buy their pricing model — which means when AWS-SES jumps the rate next year, your unit economics break. You can pass it through, or eat it. Neither is a healthy choice.
And you buy their feature roadmap. Want to ship per-recipient region pinning because your healthcare customer needs EU residency? You can't, until your upstream supports it. Want to attach a custom Return-Path domain to align DMARC? Same.
The list of things that are easier when you own the MTA
This is the list we kept while deciding. Each item is something we'd have to either work around (slowly, partially) or beg for from an upstream:
- Per-(IP × domain × provider) reputation tracking. Inbox placement isn't an account-wide property; it's a per-pair property. Owning the MTA means we own the SMTP transaction record, so we can build the reputation matrix natively.
- Provider-aware routing. Knowing the recipient's MX provider, looking up our last 24h success rate at that provider per IP × domain pair, and choosing accordingly. Impossible without owning the SMTP-level retry decisions.
- IP warmup that adapts to actual reputation. Not a 14-day timer. A curve that tightens for Gmail when Gmail starts deferring, but keeps Yahoo at the planned pace because Yahoo is fine.
- Per-domain DKIM keys. Most ESP-on-ESP wrappers share signing infrastructure with their upstream. We generate a per-account, per-domain RSA key, store it on disk in a tmpfs mount inside the MTA container, and use it directly in our Haraka DKIM plugin.
- RFC 8058 list-unsubscribe-post on every send. Gmail's bulk-sender requirements demand it; if your upstream doesn't enable it by default, you can't enable it for your customers.
- Custom Return-Path domain. Strong DMARC alignment requires the bounce envelope to align with the visible From: domain. Setting
MAIL FROM:per-customer requires SMTP-level control. - MTA-STS and TLS-RPT publishing. Modern deliverability hygiene that the recipient mailbox providers grade you on. Hard to do behind a layer of indirection.
- Region pinning per send. "This send must originate from an EU IP because the recipient is in Germany." Trivially expressible when the dispatch layer is yours.
- Bounce parsing that maps to your taxonomy. Different upstreams classify bounces differently. We parse the SMTP diagnostic ourselves so our event types are consistent across regions.
The cost — what you sign up for
Running outbound MTAs is not glamorous. Here's the rough shape of what you commit to:
- rDNS, PTR, port 25. You need bare-metal hosts on networks where port 25 isn't blocked, with rDNS set per IP, with PTR records aligned to your HELO and DKIM domains. That ruled out most public clouds. We landed on OVH bare metal in Gravelines (FR) and BHS (Quebec) — operators who let us set rDNS via their API and don't sandbox new tenants for 90 days.
- IP warmup capital. You buy IPs (€5-€30/mo each, depending on provider). Each one starts at 50/day. Math: you need a slow ramp, and you need to allocate to the right customer when the time comes. You also need to retire IPs when reputation tanks, with grace periods so customers aren't surprised.
- Operational pager. An MTA that's down means customers can't send. We run a watchdog cron that resurrects unhealthy containers within a minute, but the boring on-call obligation is real.
- FBL ingest and complaint handling. Yahoo, Microsoft, Google all expose Feedback Loop or Postmaster APIs. Wiring them into your suppression list within minutes of a "Spam" click is what separates a 0.05% complaint rate from a 1% one. Owning the pipeline means you can react.
- The thing nobody talks about: GDPR sub-processor changes. Customers want a sub-processor list. If you wrap SES, your sub-processor list is "AWS, Inc." and every change AWS makes to its sub-processors flows through to you. Owning the MTA means your sub-processor list contains you and OVH, which is short and stable.
Where we cut the choice short
We didn't build everything from zero. We use:
- Haraka — the Node-based MTA that powers the actual SMTP conversations. Plugin model is excellent, and we wrote our own DKIM signing + provider-routing plugins on top of it.
- Postgres for state (accounts, domains, IPs, suppressions, contact base).
- ClickHouse for the deliverability brain — the per-(IP × domain × provider) reputation matrix, queried in real time by the worker on every send.
- Redis for queue + rate-limiting.
- Caddy for TLS termination at the edge.
We didn't write our own SMTP parser, our own TLS stack, or our own DKIM canonicalization library. Those are full-time jobs other people do well.
What you get as a customer
Concretely: when you send an email through us, the SMTP transaction with the recipient's server is one we own. We see the response code, we record it, we route based on it, and we expose it back to you in the dashboard. When Gmail returns "421 4.7.0 IP not in whitelist", we see which IP, log why, and tighten that IP's cap for Gmail specifically while leaving the rest of your traffic unaffected.
Most ESP wrappers can't do that. Many won't tell you they can't.
The point — and the catch
Running your own MTA is the un-sexy answer to a question most companies prefer to gloss over: do you actually own the deliverability stack, or are you reselling someone else's? When the deliverability gets bumpy — and it always does — that ownership is the difference between fixing the problem and writing a status-page incident.
The catch is honesty: this approach takes longer to ship, costs more to operate, and sometimes loses to a wrapper-on-AWS-SES that took 4 weeks to build. We've had customers say "your stack is overkill for my SaaS." They're right. They use Postmark, and they're happy. But for the customers who hit deliverability walls — most B2B above ~50k sends/month — the overkill is exactly the point.
Send us hate-mail or kind words: hello@relayly.io.