A backend engineer can wire Amazon SES inbound to a Lambda, drop the raw message in S3 and have an agent reading its own email inside a week. That is why so many startup and enterprise teams ask the same question: should we build our own SMTP server or email infrastructure instead of buying an agent inbox layer?
The first-week build is real. It is also the wrong unit of analysis. The cost lands in the months after, in reply parsing that degrades quietly, in mailbox provider rules that have changed twice since early 2025, and in a decryption requirement inside SES that a Node or Python team often discovers after the architecture diagram is already approved.
TL;DR: You can build a single-agent SES prototype in one to two engineer-weeks. You should not treat that as equivalent to agent email infrastructure. Getting to native threads, durable searchable history, per-agent or per-tenant isolation, scoped events, compliance posture, and current Google/Yahoo/Microsoft deliverability is closer to ten to sixteen engineer-weeks, plus roughly seven to ten engineer-weeks every year. Build it when raw MIME cannot leave your account or when email infrastructure is your product. Buy AgentMail when the inbox is a dependency your agents need to use, not the system your team wants to maintain.
What does the week-one SES email build cover?
The path is well documented and it works. Point MX at SES in a region where email receiving is supported, which is a subset of AWS regions rather than all of them. Write a receipt rule. Have the rule drop the message into S3 and notify a Lambda. Parse the MIME with the standard library. Store what you need. Send with the SES API.
At that scope, SES is the right tool and the build estimate holds. Everything below is what sits outside that scope.
What does a DIY SES email build miss?
The S3 action encrypts client-side, and the decryption client is Java or Ruby. SES documents this plainly: "Your mail is encrypted by SES using the S3 encryption client before the mail is submitted to S3 for storage. It is not encrypted using S3 server-side encryption," and "This encryption client is available in the AWS SDK for Java and the AWS SDK for Ruby."
If your stack is Node, Python or Go, you either run a small JVM or Ruby process purely to decrypt mail, or you restructure to avoid the S3 action. Neither is hard. Both are a surprise, and they arrive after the architecture diagram is already approved.
The S3 action also caps a stored email at 40 MB including headers.
Lambda payload limits force the round trip anyway. A synchronous Lambda invocation carries at most 6 MB of request payload, and an asynchronous one 1 MB. Any message with a real attachment exceeds that, so the message goes to S3 and the function fetches it, which is where the encryption client question becomes unavoidable rather than theoretical.
Reply parsing is heuristics all the way down. Stripping quoted text from a reply is the single highest-volume correctness problem in agent email, and there is no standard that solves it. RFC 3676 format=flowed with DelSp is the closest thing, and almost no client sets it.
Every library in the field, talon in Python and the email_reply_parser family across Node, Python and Ruby, is a bag of regular expressions tuned against a corpus from a decade ago. Most have not seen meaningful maintenance in years.
They work until a customer replies from a mail client the regexes have never seen, and then your agent quotes the entire thread back at a prospect. Plan for it as a component you keep tuning rather than a task with a completion date.
Threading is yours to keep correct. Message-ID, In-Reply-To and References get you most conversations. The rest come from clients that thread on subject, clients that drop References on long threads, and forwards that break the chain entirely. Every one of those is a conversation your agent answers with the wrong context.
The mailbox provider rules moved, and then moved again. DMARC is no longer RFC 7489. As of May 2026, RFC 9989 obsoletes both RFC 7489 and RFC 9091 on the Standards Track, with reporting split into RFC 9990 and RFC 9991.
Three changes matter for anyone holding old code. The pct= tag has been removed. Organizational domain discovery is now a DNS Tree Walk rather than a Public Suffix List lookup. A new np= tag covers non-existent subdomains.
Any DMARC handling written against 7489 is running on an obsolete specification, and any runbook that tells an engineer to roll out with pct=10 is telling them to use a tag that no longer exists.
Meanwhile, Google classifies any domain sending more than 5,000 messages a day to personal Gmail accounts as a bulk sender, counts subdomains against the primary domain when it computes that, and states that "Bulk sender status doesn't have an expiration date. Email senders that have been classified as bulk senders are permanently classified as such."
One heavy month is permanent. Target spam rates below 0.10% and treat 0.30% as the number never to reach.
Yahoo declines to publish a volume threshold at all, requires DMARC to be present and to pass, and requires unsubscribes honored within 2 days, which is a pass or fail rather than a recommendation.
Microsoft requires SPF and DKIM to pass and DMARC at least at p=none for senders above 5,000 messages a day to outlook.com, hotmail.com and live.com, effective 5 May 2025. Its enforcement is outright rejection with 550 5.7.515 rather than junk foldering. Microsoft got to hard rejection before Google did, which inverts the way most engineering teams remember this timeline.
One-click unsubscribe has a requirement nearly everyone misses. RFC 8058 needs two headers, a List-Unsubscribe HTTPS URI and List-Unsubscribe-Post: List-Unsubscribe=One-Click.
Section 4 then adds the part that gets skipped: "The List-Unsubscribe and List-Unsubscribe-Post headers MUST be covered by the signature and included in the h= tag of a valid DKIM-Signature header field." Sending both headers without listing them in h= produces a setup that looks compliant in a test send and fails at the provider.
The endpoint also has to accept POST, be idempotent, need no login or CAPTCHA, use opaque non-enumerable tokens, and survive scanner prefetch, since security appliances will POST that URL without a human involved. Build to Yahoo's 2 days rather than the 48 hours Google recommends.
Consent provenance is per-recipient state. GDPR Article 7 puts the burden of proving consent on the controller, so a subscribed column will not answer the question that gets asked. What gets asked is when this person consented, through what mechanism, to what specific processing, and can you produce it.
CAN-SPAM adds seven requirements, ten business days to honor an opt-out, and an opt-out mechanism that stays live for at least thirty days after sending. The FTC's guidance is explicit that using a vendor does not move the liability.
That is a schema decision, and retrofitting it after a year of sending is worse than designing it on day one.
What maintenance does DIY email infrastructure create?
Feedback loops are where this gets structurally hard rather than merely tedious. Gmail's feedback loop reports in aggregate and never identifies which recipient complained, so per-recipient complaint suppression is not achievable for the largest mailbox provider. You suppress on bounces, on unsubscribes, on engagement decay, and you accept a blind spot on complaints from Gmail.
Then there is the standing calendar.
DKIM keys rotate, and rotation means publishing the new selector, signing with it, and keeping the old selector published until the last message signed with it has been delivered and verified. RFC 8301 rules out rsa-sha1 and pushes keys to 2048 bits.
DMARC aggregate reports arrive as compressed XML from hundreds of receivers and are worthless unless something parses and trends them.
SES dedicated IP auto warmup runs a fixed 45-day schedule. The SES global suppression list holds an address for up to 14 days, which is a behavior your own suppression logic has to account for rather than fight.
And a small one with real consequences: an EC2 instance's default reverse DNS looks like ec2-54-x-x-x.compute-1.amazonaws.com, which is precisely the generic PTR that Yahoo names as a failure condition. PTR records are controlled by whoever owns the IP block, so a self-run MTA on EC2 starts with a deliverability handicap that SES on its own address space does not have.
How many engineer-weeks does DIY agent email really take?
These are estimates rather than measurements, and they assume one competent backend engineer who has not run a mail platform before. Adjust them against your own team and treat them as a starting point for the argument rather than the end of it.
| Capability | Build, first pass | Keep correct, per year |
|---|---|---|
| Send and receive at one address | 1 to 2 weeks | low |
| MIME parsing and attachment handling | 1 week | low |
| Reply parsing and quoted-text stripping | 1 week | 1 to 2 weeks, ongoing, never finished |
| Threading across real-world clients | 1 to 2 weeks | 1 week |
| Durable searchable message store | 2 to 3 weeks | 1 week |
| Per-agent or per-tenant isolation | 2 to 3 weeks | 1 to 2 weeks |
| SPF, DKIM, DMARC and key rotation | 1 week | 1 week |
| Bounce, complaint and suppression handling | 1 to 2 weeks | 1 week |
| One-click unsubscribe to RFC 8058 | 3 to 5 days | low |
| Consent provenance and audit trail | 1 week | 1 week |
| Total | roughly 10 to 16 weeks | roughly 7 to 10 weeks per year |
At a simple example loaded cost of $150,000 per engineer-year, seven to ten engineer-weeks of annual maintenance is roughly $20,000 to $29,000 every year after the first build. AgentMail starts at $0 and scales to $200/month for 150 inboxes before enterprise pricing. The number that usually decides it is the second column, because the first column is a project with an end date and the second is a permanent claim on someone's attention.
One storage note worth knowing before you model this: S3 bills a minimum of 128 KB per object in its infrequent access and archive tiers. A corpus of small emails moved to a cheap tier does not get cheaper in proportion to its size, and the cheap-tier plan is often where DIY storage math quietly stops working. We are not quoting S3 per-gigabyte figures here because the pricing page renders client-side and we could not verify current numbers directly.
When should you still build email infrastructure yourself?
Raw MIME cannot leave an account you control, for residency or regulatory reasons a vendor contract will not satisfy, and your required region is one where SES receiving is available.
You have high steady outbound volume behind a small number of addresses, where per-inbox pricing is the wrong unit and owned IP space pays for itself.
You are building a mail gateway rather than an agent inbox, in which case SES Mail Manager is closer to your shape than any agent email product.
Your mail is machine-generated with a bounded MIME surface, where the parsing problem is small because you control both ends.
You already employ deliverability as a competency. If someone on the team reads DMARC aggregate reports as part of their job, the maintenance column above is already staffed and the calculation is different.
What hybrid email architecture do most teams land on?
The decision is rarely all of one thing.
Bulk and templated outbound, where the reply surface is a single address and volume is the cost driver, runs well on SES or a sending platform. Conversational agent mail, where each agent needs its own identity and the value is in remembering the thread, runs on a hosted inbox layer.
Teams that split it this way stop paying per-inbox pricing for their newsletter and stop building a message store for their agents.
If you already have SES in production, that split is the cheapest move available, and it does not require throwing away the work you have done.
What does an agent inbox layer actually replace?
AgentMail is the hosted inbox layer that removes the parts of DIY email infrastructure most teams underestimate. Six of them map directly onto the sections above.
- Reply parsing. Agents read the current human reply from
extracted_textandextracted_htmlinstead of owning a heuristic parser. - Threading. AgentMail creates native threads and keeps messages, attachments, search, and reply context available as API resources, instead of reconstructing conversations from raw headers forever.
- Storage. Every public plan includes it: 3 GB on Free, 10 GB on Developer, 150 GB on Startup, and custom storage on Enterprise, instead of bolting persistence onto S3 objects later.
- Tenant isolation. Pods give each tenant isolated inboxes, domains, threads, drafts, scoped API keys, and scoped webhooks, instead of one routing table for every customer or agent.
- Eventing. Agents receive real-time events through webhooks or WebSockets, instead of polling S3 or wiring SNS/Lambda fanout.
- Framework access. A hosted MCP server serves Claude, Cursor, Codex, and other MCP clients, instead of teaching every agent framework your custom email API.
For enterprises, AgentMail also publishes BYO cloud deployment, EU-region cloud, dedicated IPs, SOC 2, and OIDC/SAML SSO.
That does not make compliance disappear. It moves the inbox, threading, retention, tenant isolation, eventing, and DMARC/deliverability maintenance calendar out of your product backlog.
AgentMail gives your agents real inboxes. Create inboxes via API. Send and receive Emails with 0 complexity. Free to start.
