EdgeMail: The $0/Month Email Platform
Let me tell you about the email problem.
I needed transactional email for ArgoBox — password resets, notifications, contact form submissions. The obvious answer is a service like SendGrid, Mailgun, or Postmark. They’re reliable, well-documented, and cost somewhere between $15-30/month for basic usage.
But I’m running everything else on Cloudflare’s free tier. My site costs $0/month to host. My DNS is free. My CDN is free. My DDoS protection is free. Paying $20/month for email felt wrong when Cloudflare offers Email Routing for free.
The problem? Email Routing receives email, but it doesn’t send email programmatically. It doesn’t give you an API. It doesn’t store messages in a queryable database. It routes incoming mail to another address and calls it a day.
So I built the rest.
The Series at a Glance
| Part | What It Covers | Key Theme |
|---|---|---|
| Part 1: The Vision (this page) | Why serverless email, what it replaces, how it started | Don’t pay for infrastructure you can build |
| Part 2: Workers Architecture | Cloudflare Workers, D1 SQLite, R2 storage, KV config | Serverless isn’t just a buzzword |
| Part 3: The 61 Endpoints | API design, auth, mailbox management, threading | Building an email API from scratch |
| Part 4: Extracting from a Monolith | How EdgeMail went from ArgoBox module to standalone | The messy art of extraction |
| Part 5: Open-Sourcing & Lessons | What I learned, what I’d change, what’s next | Making it useful for others |
What EdgeMail Actually Is
EdgeMail is a serverless email backend built entirely on Cloudflare’s platform:
- Workers — The compute layer. Handles all API requests at the edge.
- D1 — SQLite database at the edge. Stores messages, mailboxes, threading data.
- R2 — Object storage. Stores attachments and large message bodies.
- Email Routing — Receives incoming email and triggers a Worker.
- KV — Key-value store for configuration, rate limits, session data.
Total infrastructure cost: $0/month on Cloudflare’s free tier. The Workers free tier gives you 100,000 requests/day, D1 gives you 5GB storage, R2 gives you 10GB. For a personal email backend, that’s more than enough.
How It Started
EdgeMail didn’t start as a project. It started as a module inside ArgoBox.
I needed ArgoBox to handle contact form submissions. Someone fills out the form, the server needs to store the message and send me a notification. Simple enough — I wrote a Cloudflare Worker that accepted POST requests, stored the message in D1, and forwarded a copy to my personal email via Email Routing.
Then I wanted threaded conversations. If someone replied to my response, I wanted the thread to stay together. That meant message IDs, references headers, and a threading algorithm.
Then I wanted mailbox management. Archive, delete, star, mark as read. That meant more endpoints.
Then I wanted admin visibility. How many messages this week? What’s the response time? Any bounces? That meant analytics endpoints.
Before I knew it, the “contact form handler” was a 9,200-line TypeScript application with 61 API endpoints, spread across 6 packages, handling everything from MIME parsing to attachment storage to rate limiting.
It was too big to live inside ArgoBox. It needed to be its own thing.
Who Would Use This?
I built EdgeMail for myself, but the use case is broader:
- Developers who want programmatic email without monthly fees
- SaaS builders who need transactional email during the early phase when $20/month matters
- Homelab enthusiasts who want to own their email infrastructure
- Anyone tired of depending on third-party email APIs for basic functionality
You don’t need EdgeMail if you’re sending 100,000 emails a day. That’s SendGrid territory. But if you’re sending 50-500 transactional emails per month? A $0/month serverless platform is hard to beat.
The Technical Bet
Building on Cloudflare Workers was a deliberate choice with trade-offs:
Advantages:
- Zero cold starts (Workers are always warm at the edge)
- Global distribution (your email API is fast everywhere)
- Free tier that’s genuinely usable
- SQLite semantics via D1 (no ORM needed, just SQL)
Trade-offs:
- Worker size limits (1MB compressed)
- D1 is eventually consistent for reads after writes
- No long-running processes (Workers have a 30-second CPU time limit)
- Vendor lock-in (this only runs on Cloudflare)
I was already all-in on Cloudflare for ArgoBox, so the lock-in wasn’t a new risk. And the constraints actually forced good architecture — small, focused Workers instead of monolithic backends.
Next up: Part 2 — Workers Architecture — How D1, R2, KV, and Email Routing work together to build a complete email backend at the edge.