9 hours ago
Every few weeks someone on X starts a fight about email providers. Resend vs Postmark vs Loops vs SendGrid vs Mailgun. People post pricing screenshots. Someone declares Postmark has the best deliverability. Someone else swears by Loops because of the API. Two replies down, a guy says he just runs Postfix on a $5 droplet and has never had a problem.
Most of these arguments miss a small detail. Resend, the favorite of the new wave of developer-friendly email APIs, runs on top of Amazon SES. Every email you send through Resend is queued by Resend, then handed off to SES, which actually delivers it. The clean API and the React Email components are real value. The deliverability is SES's deliverability. You are paying a premium for the wrapper.
This is not a knock on Resend. It is a useful frame. When people argue about email providers, the deliverability conversation is largely a conversation about whose IP pools you share and how careful they are about who they let on those pools. SES has the largest pools and a decade-plus of reputation built up with Gmail, Outlook, and the rest. Postmark has the most ruthlessly curated pools and the strongest stated stance on rejecting senders who would hurt them. Resend, Loops, and most other modern providers sit on top of SES.
For transactional mail from a properly configured sender, the deliverability difference between these options is negligible for almost every business. The variable that actually moves the needle is whether your DKIM, SPF, DMARC, and bounce handling are set up correctly. Get those right and your mail reaches the inbox. Get them wrong on any provider and it lands in spam.
If SES is this good, why isn't everyone already on it? Because the SES setup story is famously bad.
You provision a DKIM identity. You configure a custom MAIL FROM. You create a configuration set. You wire up an SNS topic for bounce and complaint events. You write a webhook handler that auto-confirms the SNS subscription on the first call. You implement a suppression list that respects permanent bounces and complaints so AWS does not throttle your account. And you remember to stamp the configuration set on every outgoing message so the events actually route back to your webhook. Miss any one of those and your sender reputation tanks.
Every comparison article admits this in the same paragraph. SES is excellent, but onboarding requires real AWS knowledge. The standard estimate is 4 to 16 hours of engineering time for a first-time setup, assuming you know what you are doing.
This is the entire reason managed providers exist. You pay them $20 or $50 a month to not think about DKIM. The economics are bad but the trade was real. Building this correctly once is annoying. Building it correctly across three or five projects is a job nobody wants.
There is a common assumption that SES is "for high volume" and the managed providers are "for small senders." That has it backwards.
At small volume the per-email cost barely matters. A few thousand emails a month on any provider is cheap. What matters at small volume is deliverability, because losing even one in five password reset emails to spam will damage your product faster than almost anything else you can break. SES gives you the same shared IP pools that back Resend and a dozen other resellers. The first 3,000 messages a month for the first twelve months are free. After that you are paying pennies.
The argument against SES has always been the engineering hours. If a language model in your editor can do the entire setup correctly in ten minutes, the engineering hours argument disappears. The cost comparison stops being "$10 for SES vs $20 for Resend" and starts being "two correctly configured providers at slightly different prices, one of which is the one the other one is built on." Once the setup is solved, the calculus changes for every project size, not just the ones sending a million emails a month.
A short note on the Postfix on a droplet crowd, because the X arguments always include them. Running your own SMTP server is legal, technically possible, and almost always a mistake for outbound transactional mail.
Gmail, Outlook, and Yahoo increasingly reject mail from IPs without established reputation. Your $5 droplet has none. New IPs land in spam by default until you warm them up with weeks of low volume, high engagement sending. You also need correctly configured SPF, DKIM, DMARC, reverse DNS, working bounce handling, and to stay off about thirty different blocklists. None of this is hard in isolation. All of it together is a part-time job for someone who would otherwise be building product.
When the SMTP guy says he has never had a problem, it usually means one of two things. He sends low volume to forgiving recipients. Or a large percentage of his mail is silently landing in spam and he has no idea, because he is not measuring it.
I spent about a day pair-programming with Claude Code on a skill that turns the entire SES setup story into one command per project. It is called aws-ses and it is free.
Download: https://s3.biznitos.com/curator/suploads/ff5a6346-7357-43eb-9ef8-1bcfc6d52445.zip
The skill is language agnostic. It ships with quickstarts for Node, Rails, Python, Go, and Elixir, plus a porting guide for anything else. When you invoke it inside a project, Claude Code looks at your dependency manifest, picks the matching quickstart, and writes the code into your project directly.
What it provisions on AWS:
ses:SendEmail and ses:SendRawEmailWhat it writes into your app:
ses_suppressions table with an upsert pattern that increments an event counter on repeat hitsOut of the box, sending to bounce@simulator.amazonses.com results in a row in ses_suppressions within 30 seconds, and the next attempt to that address is dropped without contacting SES at all.
Six steps. Total elapsed time about ten minutes once your AWS CLI is authenticated and your app is deployable.
SKILL.md and asks for your project slug, domain, sender address, and a few other inputs.scripts/init_account.sh once per AWS account. This confirms production mode and enables account-level suppression as a safety net.scripts/setup_project.sh, which generates a 256-bit URL secret, provisions every AWS resource, and emits output/<slug>/env.txt and output/<slug>/dns.txt. You paste the env vars into your host and the DNS records into Cloudflare or Route53. SES verifies in minutes.The webhook authentication choice is worth a sentence. Most SES integrations use SNS cryptographic signature verification, which requires fetching a certificate, parsing it, and reconstructing a canonical string in exactly the right field order. Easy to get subtly wrong. Different in every language. This skill uses a different approach: a 256 bit random secret baked into the webhook URL path, compared constant-time in the handler. Simpler, identical in every language, no crypto code at all. The tradeoff is that you must keep the URL out of access logs and error trackers. For infrastructure you control, that is a non-issue.
If you are on something other than the five included languages, the skill ships with PORTING.md. It is a walkthrough for Claude Code, or for you doing it manually, that covers the four pieces in dependency order. Suppression list first, then mailer, then webhook handler, then event processor. Plus a verification checklist with eight concrete tests that should all pass before you call the implementation done.
The SPEC.md document next to it is the actual contract. Resource naming, env var conventions, the webhook handler flow, every SES event schema with the exact fields you need to handle, the suppression upsert semantics, the constant-time comparison primitive for each major language. Hand SPEC.md and PORTING.md to Claude Code and ask it to implement the skill for Rust or Java or PHP, and it will do a defensible job.
Email setup was the kind of work that justified paying a managed provider out of pure pragmatism. Even if you knew SES would do the job, the hours of fiddly configuration made $20 a month look reasonable by comparison. With a model in your editor that can do the entire setup correctly, that justification dissolves. You get the deliverability of one of the biggest sending operations on the internet, the pricing of pure AWS infrastructure, and the engineering experience of having paid for a managed product.
The pattern is generalizable. Any provisioning dance you find yourself doing across multiple projects is a skill waiting to be written, and once it is a skill it is one command forever.
Download the skill: https://s3.biznitos.com/curator/suploads/ff5a6346-7357-43eb-9ef8-1bcfc6d52445.zip