The cheapest production stack we could find, fully priced out at 1M req/month.
Cloudflare Workers + D1 + R2 + Queues, with the bill spelled out per line item. The headline number is small. The why-it's-small is the interesting part.
1 million requests, 5 GB of database, 10 GB of file storage, a queue, a real domain. Total monthly cost: $5. That's not a typo. The math below.
The hypothetical app
A production SaaS. Real numbers from a side project I shipped six months ago, scaled up:
- 1,000,000 HTTP requests/month (the API)
- 3,000,000 database reads/month (D1)
- 200,000 database writes/month (D1)
- 5 GB of stored rows (D1)
- 10 GB of stored files (R2)
- 50 GB of file egress to users (R2)
- 500,000 queue messages/month (background jobs)
- A custom domain on Cloudflare (free)
The bill, line by line
| Service | Free tier | This app's usage | Cost |
|---|---|---|---|
| Workers (requests) | 100k/day = 3M/mo | 1M/mo | $0 (under free tier) |
| Workers (CPU time) | 10ms/req | ~5ms avg | $0 |
| D1 (storage) | 5 GB | 5 GB | $0 (at the line) |
| D1 (reads) | 25M/day = 750M/mo | 3M/mo | $0 |
| D1 (writes) | 50k/day = 1.5M/mo | 200k/mo | $0 |
| R2 (storage) | 10 GB | 10 GB | $0 (at the line) |
| R2 (egress to users) | None — it's $0/GB | 50 GB | $0 (R2 has no egress fee) |
| R2 (Class A operations) | 1M/mo | 200k/mo | $0 |
| Queues | None — billed from request 1 | 500k/mo | $0.20 |
| Workers Paid plan minimum | — | required for Queues | $5.00 |
| Total | $5.20/month |
The asterisk
The $5 minimum is the Workers Paid plan, which you only need if you use Queues, Durable Objects, Cron Triggers, or want to remove the daily request cap. If you skip Queues and stay on the free tier, this entire stack costs $0/month. Yes, zero. For a real production app on a real custom domain.
I am aware this sounds like marketing copy. It's not. This is what the Cloudflare dashboard says when I check my bill. I keep waiting for an asterisk and there isn't one.
What this app would cost on AWS
Same workload, conservative AWS estimate:
| Service | Approx cost |
|---|---|
| Lambda (1M req, 100ms avg, 256 MB) | $0.20 |
| API Gateway (1M req) | $3.50 |
| RDS Postgres t4g.micro | $13–18 |
| S3 storage (10 GB) | $0.23 |
| S3 egress (50 GB) | $4.50 |
| SQS (500k messages) | $0.20 |
| CloudFront (50 GB) | $4.25 |
| Route 53 | $0.50 |
| Total | ~$26–31/month |
Same workload, ~5–6x the bill. Plus you spend a weekend wiring it up.
R2 has no egress fee. That single decision wrecks half the AWS bill on its own.
What breaks when you scale
The free tier covers a lot, but the math changes meaningfully at:
- ~10M requests/month — you blow through the Workers free tier on big days. Add ~$5 per extra 10M.
- D1 hits 5 GB — extra storage is $0.75/GB/mo. Cheap, but worth knowing.
- R2 hits 10 GB stored — extra storage is $0.015/GB/mo. Still a rounding error.
- Heavy Durable Object traffic — DO is billed by request + duration. Real-time apps watch this number.
For a typical SaaS at 50k MAU, you're looking at $20–40/month. At AWS-equivalent workload, you'd be at $200–400.
Why this matters
Your runtime cost is the floor on your unit economics. If your bare infra costs $30/customer/month, your subscription has to clear that just to be break-even. If it costs $0.30, you can experiment with pricing, with free tiers, with churn. The cheaper the floor, the more business model you have.
$5 to run a small SaaS. $0 if you're cleverer than I am.
The Cloudflare bet is simple: edge + no-egress + opinionated services. The price is the side effect of the architecture. Once you've shipped on it, the AWS console feels like time travel.
Ship the cheap stack from a chat prompt.
buildr scaffolds Workers + D1 + R2 + Queues by default and deploys to your Cloudflare account. Same $5 stack, just typed for you.
Build my app free