Resend is the better developer experience and the faster path to a first send. Mailgun gives you more control over sending domains, routing, and per-domain reputation, which starts to matter when one application sends on behalf of many customers. The choice that actually decides your deliverability is neither: it is which domain you send from.
The short version
| Resend | Mailgun | |
|---|---|---|
| Time to first send | Minutes | Longer; more configuration up front |
| Developer experience | Excellent, modern SDKs, React email templates | Functional, older surface area |
| Multiple sending domains | Supported, simpler model | Strong; built around per-domain control |
| Routing and inbound | Limited | Mature routing, inbound parsing |
| Logs and debugging | Clean, readable | Deeper, more raw detail |
| Best fit | Product and auth mail for one company | Many domains, many tenants, per-domain reputation |
If you are one company sending your own transactional mail, Resend will get you further faster and you should probably use it. If you are building something that sends on behalf of other businesses, the per-domain control is worth the extra setup.
The thing that actually broke
Here is the part I would want someone to tell me before a migration, because it cost me more thought than the provider comparison did.
Swapping providers is a small code change. Swapping providers safely is a DNS change, and DNS is where the failure lives. When the CRM moved to Mailgun, the sending domain was a subdomain, mail. the root. That was deliberate, and it is the reason the migration worked at all. The DNS looked like this:
| Root domain | Mail subdomain | |
|---|---|---|
| SPF | Registrar include only, no Mailgun | Mailgun include ✅ |
| DKIM | The old provider’s key | Mailgun’s key ✅ |
Send as the root domain through Mailgun and the mail leaves SPF- and DKIM-unaligned, and it lands in spam. Nothing in the application logs tells you this. The provider reports a successful send. The message simply does not arrive, or it arrives in a folder nobody reads.
The failure is silent, which is what makes it dangerous. A queue that reports 100% delivered and a customer who says they never got the email are describing the same event.
Why a subdomain is the right default
Two reasons, and the second one is the one people learn the hard way.
First, reputation isolation. If your product sends a badly-timed campaign and the domain takes a reputation hit, you want that contained. A subdomain means your invoices and password resets are not sharing a reputation with your marketing.
Second, you can add a provider without touching a record other services depend on. A root SPF record usually already carries an include for your registrar’s mail forwarding, your calendar, your helpdesk. Adding a provider there means editing a live record that other things rely on, and SPF has a hard limit of ten DNS lookups. Replacing rather than merging that record is the classic way to break email you did not know you had.
If you do need to send from the root later, the order matters: add the root as a sending domain with the provider, publish its DKIM, merge the new include into the existing SPF rather than replacing it, and only then point the application at the new sender.
Split by lane, not by provider
The CRM ended up running two separate email paths, and I would do it this way again:
- The customer lane — mail the product sends on behalf of a tenant. Per-workspace sender resolution, plan quotas, a warm-up ramp for new senders, every send logged.
- The platform lane — the product emailing its own users: onboarding, lifecycle, billing. Deliberately not subject to tenant quotas.
That second point is the one worth stealing. If platform mail runs through the same quota system as customer mail, then a tenant who exhausts their sending cap also stops receiving “your trial is ending” and “your payment failed.” You have coupled your own revenue notifications to a customer’s usage limit. Keep the lanes separate in code, not just in intent.
It is also completely reasonable to leave authentication mail on one provider while product mail moves to another. Users care that the reset link arrives, not whose logo is in the SMTP headers.
How I would choose now
- One company, your own mail? Resend. The developer experience is genuinely better and you will ship sooner.
- Sending for other businesses, on their domains? Mailgun. Per-domain control and routing are the whole job.
- Either way, send from a subdomain and verify SPF and DKIM for that exact hostname before you move production traffic.
- Make the sender one environment variable. On the CRM it is a single value. That is what made the change reversible, and reversibility is worth more than picking right the first time.
What to check before you switch
- Send a test to a Gmail address and open Show original. You want
SPF: PASSandDKIM: PASSwith the signing domain matching your From address. - Confirm your SPF record still resolves under ten DNS lookups after the change.
- Check whether anything else already sends as that domain. Registrar forwarding is the usual surprise.
- Warm up gradually if the domain has no sending history. Volume from a cold domain looks exactly like a compromised account.
- Keep a rollback: one environment variable, not a redeploy.
FAQ
Is Resend or Mailgun better?
Neither in the abstract. Resend is the better developer experience and the faster first send. Mailgun gives more control over sending domains and routing, which matters once you send on behalf of many customers.
Why did my email start going to spam after switching providers?
Almost always SPF and DKIM alignment rather than the provider. If the domain still publishes the old provider’s include and key, mail sent through the new one leaves unaligned. Check the exact sending hostname, including the subdomain.
Should I send from my root domain or a subdomain?
A subdomain, by default. It isolates your application’s sending reputation and lets you add a provider without editing an SPF record other services already depend on.
Can I run two email providers at once?
Yes, and it is common. Split by lane: authentication on one, product and lifecycle on the other. Each needs correct SPF and DKIM for the domain it actually sends from.
Does the provider affect deliverability much?
Less than people expect. Both are reputable senders. Your domain authentication, your sending history, and whether recipients want your mail matter considerably more than the logo on the dashboard.
If you are wiring email into a product and want it to work the first time, tell me what you are building. Related: other tool comparisons, Postgres row-level security, and how I build web apps.