DEV Community

niuniu
niuniu

Posted on

I Ran My Entire Side Project on Cloudflare Workers Free Tier for 6 Months — Vercel Would Have Charged Me $240

Six months ago I moved my side project (a link-in-bio tool with ~2,000 daily users) from Vercel Hobby to Cloudflare Workers Free. Not because Vercel is bad — it's excellent — but because I read the fine print: Hobby is non-commercial only, and I was about to add a tip jar.

Here's the honest 6-month report.

The Setup

  • Before: Vercel Hobby, Next.js app, ~50GB bandwidth/month
  • After: Cloudflare Workers + Pages + KV + R2, same app rewritten as a Worker
  • Migration time: One weekend (8 hours, mostly rewriting API routes as Worker handlers)

The Bill

Month Vercel (projected) Cloudflare (actual)
1 $20 (bandwidth overage) $0
2 $20 $0
3 $40 (added tip jar → commercial) $0
4 $40 $0
5 $40 $0
6 $40 $0
Total $200 $0

Cloudflare Workers free tier: 100,000 requests/day, 10ms CPU time per request. My usage peaked at 67,000 requests/day. Never hit the limit.

Performance Numbers (Real, from Cloudflare Analytics)

Metric Vercel (before) Cloudflare (after)
Cold start p50 340ms 0ms (no cold starts)
Cold start p99 1.2s 0ms
TTFB p50 (US) 89ms 23ms
TTFB p50 (EU) 156ms 31ms
TTFB p50 (Asia) 410ms 45ms

The Asia number is the killer feature. Vercel runs in a few regions; Cloudflare runs in 300+ cities. My Singapore users went from 410ms to 45ms. That's not an optimization — it's a different product.

What Broke (The Honest Part)

  1. Node.js APIs. Workers isn't Node. fs, path, crypto (partially) don't exist. I had to replace bcrypt with WebCrypto subtle.digest. Took 3 hours of "why is this undefined" debugging.
  2. No persistent connections. WebSockets need Durable Objects (paid tier). I punted and used polling. Users didn't notice, but it felt dirty.
  3. KV consistency. KV is eventually consistent. I wrote a session token, immediately read it back, got null. Spent 2 hours thinking my code was broken. It wasn't — KV just hadn't propagated. Solution: write to KV, return the value from memory, don't re-read.
  4. 10ms CPU limit. Image resizing hit the limit. Had to move that to a queue + consumer Worker. More architecture, more moving parts.

The One Feature That Almost Made Me Switch Back

Preview deployments. Vercel's git-integration previews are magical: push a branch, get a URL, share it. Cloudflare has previews too, but they're per-branch and require Wrangler CLI setup. It's fine for me, but my non-technical co-founder couldn't figure out how to preview a change. Vercel's DX is genuinely better here.

The Uncomfortable Math

Cloudflare Workers free tier is 100,000 requests/day. Vercel Hobby is 100GB bandwidth. These sound comparable until you realize:

  • A single API response is ~2KB. 100,000 requests = 200MB/day = 6GB/month.
  • Vercel counts bandwidth, Cloudflare counts requests.
  • My app is API-heavy, small payloads. Cloudflare wins.
  • If I were serving video or large images, Vercel's bandwidth model might actually be cheaper.

The free tier that's better depends entirely on your payload shape. Nobody talks about this.

Would I Do It Again?

Yes, but with eyes open. The 6-month savings ($240) funded my domain renewal and a year of Proton Mail. The tradeoff is DX — I miss Vercel's polish, but I don't miss the invoice.

I sketched the migration checklist and the KV consistency workaround with MonkeyCode: https://ly.cyberserval.tech/iIETXiF

What's your free tier horror story? The one where you hit a limit at 2am and had to frantically upgrade?

Top comments (0)