Cloudflare Workers vs a Traditional VPS: When the Edge Wins and When a $6 Box Still Does the Job
Daniel Park
September 27, 2026
A few years ago, the default answer for hosting a small web app was a VPS. Rent a Linux box for a few dollars a month, install your runtime, put Nginx or Caddy in front, and you were done. Today a lot of developers skip that entirely and deploy to Cloudflare Workers, where there is no server to patch, code runs in hundreds of cities, and the free tier is generous enough that many side projects never pay a cent.
Both camps are right about something. I have moved projects onto Workers and been delighted, and I have moved projects off Workers and back onto a plain VPS and been equally relieved. The difference was never “edge is modern, VPS is old.” It was what the application actually did, where its data lived, and which constraints I was willing to design around.
This is a practical comparison for developers deciding where to put a small-to-medium application: what each model is, what it really costs, where the performance claims hold up, and where each one will eventually push back.
Two very different models
A VPS is a virtual machine. You get CPU, memory, disk, a public IP address, and root access. Anything that runs on Linux runs there: any language, any database, long-running background workers, WebSocket servers, cron jobs, a queue, a cache, all on the same box. It lives in one data center, and you are responsible for everything above the hypervisor: OS updates, firewall, TLS, backups, monitoring, and deployment.
Cloudflare Workers is a serverless platform. You deploy functions, written mostly in JavaScript or TypeScript, with WebAssembly and Python as other options, and Cloudflare runs them in V8 isolates across its global network. An isolate starts in milliseconds, so cold starts are essentially a non-issue compared with container-based serverless. There is no server, no OS, and no process you manage. Each request runs your code, close to the user, within limits on CPU time, memory, and outbound requests.
Around Workers, Cloudflare has built a whole platform: KV for globally replicated key-value data, D1 for SQLite-based databases, R2 for object storage without egress fees, Durable Objects for strongly consistent state and WebSocket coordination, Queues, Cron Triggers, and Hyperdrive for connecting to an external Postgres database efficiently. That ecosystem matters, because an application on Workers usually ends up using several of these pieces rather than a single database on local disk.
Cost: two very different bills
A VPS bill is flat. A small instance from a budget provider runs somewhere in the four-to-twelve-dollar range per month, with a generous bandwidth allowance. Whether you serve ten requests or ten million, the price is the same until the box runs out of capacity. Then you resize, and the price steps up.
Workers bills usage. At the time of writing, the free plan includes around 100,000 requests a day with a small CPU-time budget per request. The paid plan starts at a monthly minimum of about five dollars, which includes millions of requests and a large block of CPU time, then charges small amounts per additional million requests and per million CPU milliseconds. Cloudflare does not charge for bandwidth on Workers, which is a genuine differentiator for anything that serves a lot of data. The storage products each have their own free tiers and usage pricing.
For most small projects, both options land in the single digits per month. The differences show up at the edges:
- Spiky or unpredictable traffic favors Workers. A post that hits the front page of a big forum costs a few extra cents instead of melting a VPS.
- Heavy, steady CPU work favors a VPS. Image processing, PDF generation, or big data transforms burn CPU milliseconds on Workers, while a VPS gives you all its cores at a flat rate.
- Very low traffic favors Workers. A tool that gets fifty requests a day fits entirely in the free tier.
- Many small services can go either way. Ten tiny apps can share one VPS for one price, or run as ten Workers that are each essentially free.
One cost people miss on the VPS side: time. Patching, backups, and the occasional 2 a.m. disk-full alert are part of the bill. On Workers, that time goes to learning platform limits and designing around them instead. Neither is free; they are different kinds of effort.

Performance: the edge claim, examined
The pitch for Workers is that your code runs near every user, so responses are fast everywhere. That is true for the compute. It is not automatically true for the application.
Consider a typical request: authenticate the user, read some data, render a response. If the data lives in a Postgres database in Frankfurt and the user is in Sydney, a Worker running in Sydney has to cross the planet to reach the database, possibly several times per request. The Worker starts instantly and then waits on round trips. A VPS in Frankfurt, sitting next to the database, pays the long network hop once, between the user and the server, and then does all its queries locally in under a millisecond each.
In practice, Workers is fastest when:
- The response can be computed without a central database: redirects, header rewrites, A/B routing, auth token checks, image resizing, API proxies.
- The data is cacheable or globally replicated: KV reads, cached API responses, static assets.
- The data can be sharded naturally, one Durable Object per user, room, or document, so each piece of state lives near whoever uses it.
Cloudflare knows about the database-distance problem. Smart Placement can run a Worker near its backend instead of near the user, and Hyperdrive pools and accelerates connections to an external database. Both help. But the underlying physics does not change: if all your state is in one region, a globally distributed compute layer mostly moves where you wait.
A VPS, meanwhile, is fastest for chatty workloads: many sequential database queries, in-memory caches, and long-lived connections. For users far from its region, you can put a CDN in front for static assets and cacheable pages, which closes much of the gap for read-heavy sites.
Limits you will actually hit
Workers is a constrained environment by design. Those constraints are what make it cheap and fast to start, and they are also the most common reason people move off it.
- CPU time per request. The free tier gives a very small CPU budget per invocation. Paid plans raise it substantially, but a single request is still not meant to crunch for a long time.
- Memory. Each isolate has a modest memory limit, around 128 MB. Loading a large dataset or an image library into memory can hit it.
- Not quite Node. A Node compatibility mode covers many built-in APIs, and most pure-JavaScript libraries work. Native modules, anything that expects a real filesystem, and libraries that spawn processes do not.
- Subrequest caps. There is a limit on how many outbound requests one invocation can make. Fan-out patterns that call dozens of APIs per request can run into it.
- No long-running processes. There is no server loop, no background thread that runs forever. Background work moves to Queues, Cron Triggers, Durable Object alarms, or workflows.
- Database choices. D1 is SQLite-based with per-database size limits; it suits many apps well, but it is not a drop-in for a large Postgres instance. For that, you connect to an external database, which reintroduces the distance problem above.
A VPS has limits too, but they are the familiar kind: it has however many cores and gigabytes you paid for, and when you outgrow it, you buy a bigger one or add another server. There is no framework to learn, only a machine to fill.
Operations: what you are signing up for
With a VPS, you own the stack. That means unattended security updates, a firewall, SSH hardening, TLS certificates, log rotation, backups, uptime monitoring, and a deployment process. None of it is hard, and a lot can be automated in an afternoon. You also choose how you deploy, from a plain Compose file pulled over SSH to a self-hosted PaaS layer, and that choice has its own trade-offs; the comparison of Coolify versus a plain Compose file on a VPS is where most people land next.
With Workers, there is no OS to patch and no TLS to renew. Deployment is one command with Wrangler, or a Git push if you connect a repository. Rollbacks are quick. DDoS protection comes with the network. The operational work shifts to understanding the platform: how KV consistency works, when to use a Durable Object, how limits apply, and how to debug something that only fails in one region.
For a solo developer, that shift is often worth it. Not having a server means not having a server to forget about.

Lock-in, honestly
A VPS is about as portable as hosting gets. If your provider raises prices or has a bad month, you can move a Linux server to another provider with a backup and a DNS change. Standard software, standard interfaces.
Workers code is standard JavaScript built on web APIs like fetch, Request, and Response, and frameworks such as Hono run on several runtimes, which keeps the request-handling layer fairly portable. The lock-in lives in the platform services. An app built around KV, Durable Objects, D1, and Queues has no drop-in equivalent elsewhere. R2 speaks the S3 API, so object storage is the easiest piece to move. The rest would be a rewrite of the data layer.
That is not necessarily a reason to avoid Workers. It is a reason to know which pieces you are adopting. Using Workers as a thin, portable layer with an external database keeps your options open. Building deeply on Durable Objects gets you capabilities that are hard to replicate anywhere, in exchange for staying.
The hybrid that often wins
The framing of “Workers or VPS” hides the setup I end up recommending most: both.
Put a Worker in front of a VPS. The Worker handles what the edge is good at: caching, redirects, authentication checks, rate limiting, routing different paths to different backends, and serving static assets from R2. The VPS handles what a server is good at: the database, the application logic that makes many queries, background jobs, and anything that needs a real filesystem or a long-running process.
This arrangement gives you global speed for the parts that can be fast everywhere, a flat-priced machine for the heavy lifting, and an easy migration path in either direction. As the app grows, you can move more logic into Workers where it fits, or keep the edge thin and scale the server.
Which one should you choose?
Choose Cloudflare Workers if your app is mostly request-and-response with little heavy computation; traffic is spiky, global, or very low; you want zero server maintenance; and you are comfortable designing around per-request limits and Cloudflare’s storage services. APIs, webhooks, redirect services, lightweight SaaS backends, and sites with mostly cacheable content are strong fits.
Choose a VPS if your app needs long-running processes, a traditional relational database with lots of queries per request, native libraries, heavy CPU work, or a stack that assumes a normal Linux environment. Also choose it if portability and a predictable flat bill matter more to you than global latency.
Choose both if you have a real backend but want edge caching, protection, and routing in front of it. For many small products, that is the most balanced setup available today.
The best hosting decision is the one that matches where your application’s state lives and what its requests actually do. Start there, and the “edge versus server” debate mostly settles itself.