Last month I got my annual hosting renewal email: $540/year for a VPS running three side projects that get maybe 40K requests a month combined.
I did the math. I was paying $45/month for a machine that sat idle 97% of the time. So I moved everything to Cloudflare Workers' free tier. Here's what actually happened.
The old setup vs the new setup
| DigitalOcean VPS | Cloudflare Workers Free | |
|---|---|---|
| Cost | $45/month ($540/yr) | $0 (100K requests/day free) |
| Cold start | Always-on (but I'm paying for idle) | <5ms (V8 isolates, no containers) |
| Latency | 1 region (NYC). Tokyo users: 180ms | 300+ PoPs. Tokyo users: 12ms |
| Maintenance | SSH, security patches, 2am "why is it down" | Zero. There is no server. |
| Deploy | rsync + pm2 restart |
npx wrangler deploy (8 seconds) |
The migration took one weekend
One of the projects is a URL shortener API. The entire thing on Workers + KV:
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (request.method === "POST") {
const { target } = await request.json();
const slug = crypto.randomUUID().slice(0, 6);
await env.LINKS.put(slug, target);
return Response.json({ short: `https://s.example.com/${slug}` });
}
const slug = url.pathname.slice(1);
const target = await env.LINKS.get(slug);
return target
? Response.redirect(target, 302)
: new Response("not found", { status: 404 });
}
};
Deploy:
npm create cloudflare@latest
npx wrangler kv namespace create LINKS
npx wrangler deploy
# Published https://shortener.myaccount.workers.dev in 8.2s
Three projects migrated: URL shortener, a status-page webhook, and a cron job that scrapes prices every 6 hours (Workers Cron Triggers — also free).
30 days of real numbers
- Requests served: 1.24M (avg 41K/day, peak 89K/day) — all under the 100K/day free cap
- Paid: $0.00
- P95 latency: 180ms → 23ms (my users are mostly in Asia, the old VPS was in NYC)
- Uptime incidents I had to fix: 0 (was: 2 — one OOM, one expired SSL cert)
Where free Workers will bite you (honest list)
- 10ms CPU time limit on the free tier. Fine for routing/CRUD, useless for image processing. My thumbnail generator stayed on a $6 Hetzner box.
- No long-running anything. WebSockets need Durable Objects (paid), background jobs need Queues.
-
Node.js APIs are partial. Check
nodejs_compatbefore you migrate something that usesfsor native modules. - If you blow past 100K req/day consistently, the paid plan is $5/mo for 10M requests — still 9x cheaper than my VPS.
The controversial part
Most side projects don't need a VPS in 2026. We rent whole Linux machines out of habit — because that's how we learned — then pay $40-60/month to serve JSON that a free edge function handles better. Unless you're running stateful services, game servers, or heavy CPU work, a VPS is a comfort blanket with an invoice attached.
For anything the free tier can't cover, I draft the migration with an AI pair programmer — I've been using MonkeyCode (free, open-source) to generate the wrangler configs and compatibility shims, which cut the second project's migration to about 40 minutes.
What's still on your VPS that doesn't need to be? I genuinely want to know what workload broke for you on Workers — drop it in the comments.
Top comments (0)