RUBY ON RAILS · 7 MIN READ ·

Building Euromailing: Why We Run Our Own MTA Instead of Reselling an ESP

How we built a GDPR-native email marketing platform on Rails 8.1 and KumoMTA, and why owning the sending layer changes the architecture of the whole product.

Building Euromailing: Why We Run Our Own MTA Instead of Reselling an ESP

Most email marketing platforms are a user interface wrapped around somebody else’s mail server. You sign up, you build a list, you design a campaign — and when you press send, your message is handed to SendGrid, Mailgun or Amazon SES. The platform you are paying is a tenant on infrastructure it does not control.

That model works until it doesn’t. When we started building Euromailing, we decided to own the sending layer. This post is about what that decision costs, what it buys, and how it shaped a Rails application.

The reseller trap

If you resell an ESP, three things are true and none of them are in your control.

Your deliverability is somebody else’s reputation. You share IP pools with every other customer of that provider. A spammer three accounts over can degrade your inbox placement, and there is nothing you can do except file a ticket.

Your margins are fixed by their price list. You buy at wholesale and sell at retail, and the spread is the business. When they raise prices, your product gets worse or your margin disappears.

Your data crosses whatever borders they choose. This is the one that matters most in Europe. If your customers are Dutch associations, German agencies or French retailers, “GDPR compliant” cannot mean “we signed a data processing agreement with a US provider and hoped for the best.” Contact data, open tracking and bounce logs are personal data.

Owning the MTA removes all three constraints and replaces them with a single, much harder one: you now have to be good at running mail infrastructure.

KumoMTA as the sending layer

We use KumoMTA for the actual sending. It is an open source MTA built for high-volume senders, and the important property for us is that it exposes the things a marketing platform needs to reason about — queues, per-domain traffic shaping, bounce classification — rather than hiding them behind an API.

The Rails application never talks SMTP directly to recipients. It composes, it decides, and it hands off. KumoMTA handles the parts that require years of accumulated operational knowledge: connection reuse, retry backoff, per-provider throttling, TLS negotiation.

The division of labour matters because it keeps the Rails side comprehensible:

  • Rails owns intent. Who should receive this, are they still subscribed, does this campaign respect their preferences, what does the rendered message look like.
  • KumoMTA owns delivery. How fast to send to Gmail right now, what to do with a 421, when to give up.
  • The feedback loop belongs to both. Bounces, complaints and suppressions flow back into Rails, where they become domain events that affect future sends.

That last point is where most reseller-based platforms get thin. When the ESP owns bounce handling, you get a webhook and a status string. When you own it, you can classify a hard bounce by the actual SMTP response, decide your own suppression policy, and explain to a customer exactly why an address stopped receiving.

Multi-tenancy without leaks

Euromailing is multi-tenant: many businesses, each with their own contacts, templates, campaigns and API keys. In an email platform, a tenancy leak is not an inconvenience — it is sending one customer’s campaign to another customer’s list.

We treat tenant scoping as something that must be impossible to forget rather than something developers remember. Every query path that touches contact data is scoped at a layer below the controller, so a missing where clause in a new feature cannot widen the blast radius. This is the same class of problem we wrote about in multi-tenancy strategies for Rails and Postgres row-level security.

The public API makes this sharper. Keys are scoped and rate limited, issued per account, and shown exactly once at generation time:

curl https://euromailing.com/api/v1/contacts \
  -H "Authorization: Bearer eml_live_..."

An API is a promise that other people will build on your data model, so the tenancy boundary has to hold under access patterns you did not design for.

MJML, because HTML email is not HTML

Anyone who has hand-written a responsive email template has discovered that email clients implement a fossil record of HTML. Outlook still wants tables. Gmail strips things. Dark mode inverts what it feels like inverting.

Templates in Euromailing are authored in MJML and compiled to the table soup that email clients actually accept. The compilation is part of the build path, not something a marketer does by hand, which means a template change is reviewable like any other change.

This is a small decision that removes an entire category of support ticket.

Workflows are state machines, not cron jobs

The visual workflow builder lets a customer describe automation: when someone subscribes, wait two days, send the welcome message, and if they clicked, tag them.

The naive implementation is a scheduled job that scans every contact for eligibility every few minutes. That works at ten thousand contacts and collapses at ten million.

Instead, a contact entering a workflow gets a position in that workflow, and transitions are scheduled individually. The work is proportional to the number of contacts actually moving, not to the size of the database. Solid Queue handles the scheduling, backed by Redis for the rate limiter.

Inbound mail is not an afterthought

Most platforms treat email as outbound only, which leaves the reply-to address pointing somewhere nobody reads. Euromailing routes inbound mail: replies, bounces that arrive as messages rather than SMTP responses, and unsubscribe requests sent as plain text by people who will never find your preference centre.

Routing inbound mail properly is what makes a campaign feel like correspondence rather than a broadcast.

What owning the stack actually costs

I want to be honest about the trade, because “run your own infrastructure” is advice that gets given far too casually.

You take on operational responsibility that never sleeps. IP warming is real and slow. Blocklist monitoring is a job. When Microsoft decides your ranges look suspicious on a Sunday, that is your Sunday. A reseller pays a margin to make those problems somebody else’s, and for many businesses that is the correct trade.

It is the right call when deliverability is the product, when data residency is a legal requirement rather than a preference, and when you have the operational depth to carry it. For a European platform selling to European businesses, all three were true.

The Rails part is almost boring

The stack is deliberately unexciting: Rails 8.1, PostgreSQL, Solid Queue, Redis, Tailwind. RSpec and FactoryBot for the test suite. Nothing here is novel, and that is the point — all the interesting risk in this product lives in the mail infrastructure and the tenancy model, so the application layer should be the most predictable thing in the building.

That is generally how we build at TTB Software: spend your novelty budget where the actual difficulty is, and let everything else be the boring, well-documented option that any Rails developer can pick up in an afternoon.


Building something where email deliverability, GDPR or multi-tenancy is a first-class concern rather than a checkbox? TTB Software does Rails architecture and fractional CTO work. Nineteen years of shipping this kind of system.

#kumomta-rails #email-marketing-platform-rails #gdpr-email-infrastructure #rails-multi-tenant-saas #mjml-rails-templates #self-hosted-mta

Related Articles

Last section. Then please call.

It's a phone call. That's the worst it can get.

No discovery deck. No 45-minute "qualification" call. 30 minutes, your problem, my opinion. If we're a fit, you'll know by minute 12.

Direct line — answered by Roger
+31 6 5123 6132
Mon–Fri, 09:00–18:00 CET · Currently available

OR
info@ttb.software