Vercel vs Cloudflare Pages vs Netlify: the bill that shows up during a traffic spike
The three platforms meter entirely different things. That, not the features table, is what decides the invoice on the one day traffic misbehaves.
The "Vercel vs Cloudflare Pages vs Netlify" pitch versus the bill
"Vercel vs Cloudflare Pages vs Netlify" comes up in nearly every "how do I host this" conversation, and it usually gets settled with a features comparison: framework support, preview deployments, build times. That comparison is fine for picking a platform on day one. It says almost nothing about what happens on the day traffic stops being average.
All three companies sell a version of the same promise: push to a git branch, get a URL, stop thinking about servers. Vercel leans hardest into Next.js, with framework-level optimisation for image handling and incremental static regeneration. Netlify leans into being framework-agnostic, with a marketplace of build plugins and a longer history than either of the other two. Cloudflare Pages leans into its network: over 300 points of presence and a request-routing layer built by a company that already runs a large share of the internet's DDoS mitigation.
None of the three landing pages lead with the thing that actually decides a real bill: what each platform counts as a billable unit, and what happens when that count moves somewhere nobody planned for. A marketing push. A scraper that decided your product pages were interesting. A customer's retry loop after a bad deploy. Three platforms, three different metering models, three very different outcomes for the same event.
What each platform actually meters
Read the pricing pages closely and the three platforms are not really selling the same thing at all.
Vercel's Pro plan measures usage across roughly eight separate dimensions: bandwidth, edge requests, function invocations, function duration, Active CPU time, image-optimisation transformations, and a few more depending on which features are switched on. Pro bundles 1 TB of bandwidth a month, then bills the excess per gigabyte — a rate that has moved more than once over the past year, which matters if next year's cost model is built off last year's invoice. The number of separate meters is the point: it lines billing up precisely with infrastructure cost, and it is also exactly why Vercel's pricing has a reputation for being hard to predict from the outside.
Netlify's free tier is the most generous of the three on paper: 125,000 function invocations and 300 build minutes a month before anything is billed. Its compute story is split across two runtimes — Deno-based Edge Functions, fast but with a narrower API surface, and AWS Lambda-based Functions, which support full Node.js but inherit Lambda's cold-start behaviour, independently measured in the 150-400 millisecond range. Most non-trivial Netlify applications end up running both runtimes side by side, choosing per route.
Cloudflare Pages runs on Workers by default: V8 isolates rather than full containers, which is why they do not show the same cold-start profile as a Lambda-backed function. A newer container runtime exists for workloads that genuinely need a full Node environment. The headline difference is bandwidth: Cloudflare does not charge for outbound traffic served from its own network the way the other two do, because that was already its business before it sold hosting.
| Platform | Compute billing | Bandwidth model | Cold starts |
|---|---|---|---|
| Vercel | Active CPU (Fluid Compute), function duration, invocations | 1 TB bundled on Pro, then per-GB overage | Reduced by keeping functions warm across requests |
| Netlify | Function invocations across two runtimes | Metered beyond the free allowance | Lambda Functions: ~150-400ms; Edge Functions: minimal |
| Cloudflare Pages | Workers requests and CPU time per invocation | No egress fee at the CDN/Workers layer | Near-zero on Workers isolates; container runtime for full Node |
The $23,000 afternoon
The clearest way to see the difference is not the pricing page. It is what happens during the one day traffic does not behave.
One widely discussed case put a single distributed denial-of-service incident at roughly $23,000 in bandwidth charges on a metered hosting bill, because the billing layer counted every byte of attack traffic at the standard rate. That is not a hypothetical reserved for security researchers. The same billing shape applies to a badly configured scraper indexing every product page on a site, a retry loop hammering an endpoint after a broken deploy, or a link that goes unexpectedly viral. None of those are attacks. All of them produce the same invoice shape.
The asymmetry between the three platforms shows up exactly here. On a bandwidth-metered platform, an unplanned spike is a bandwidth bill, full stop, sized by however much traffic showed up and whatever each gigabyte costs at that tier. On Cloudflare Pages, the same spike is mostly free at the network layer, because Cloudflare does not charge for egress from Workers or Pages — the cost shows up elsewhere if the spike also hammers an origin server, a database, or Workers KV reads, but the single largest historical source of bill shock for the other two platforms does not apply in the same way.
Put a rough number on it: a day that pushes an extra 500 GB through a bandwidth-metered platform lands somewhere in the low hundreds of dollars once it clears the bundled allowance, and scales linearly from there, since neither Vercel nor Netlify caps the overage. The same 500 GB served from Cloudflare's network costs nothing at the bandwidth line, though it still shows up as origin load, function invocations, or KV reads if the application does real work per request rather than serving static assets. The gap is not that one platform is cheap and the others are expensive. It is that one platform's cost for this specific event rounds to zero and the other two scale with exactly the traffic nobody planned for.
“Cost comparisons that skip the bad day are modelling the traffic that was never going to surprise anyone.”
Cold starts, warm functions, and the Active CPU question
Performance comparisons usually stop at time-to-first-byte, which flattens a real difference in how these platforms bill compute.
Vercel's Fluid Compute keeps functions warm across requests, and, more importantly for the bill, introduced Active CPU as a metering unit distinct from wall-clock duration. A function waiting on a database query or a third-party API is not burning Active CPU during that wait, only while it is actually executing instructions. For an I/O-heavy workload, which describes most CRUD APIs and most page renders that call out to a database, that is a materially different cost model than billing for the full duration a function stayed alive, wait time included. For a CPU-bound workload with little I/O, the saving is smaller, because there is little idle time left to stop charging for.
Netlify's split-runtime approach means the cold-start conversation happens twice. Edge Functions, running on Deno at the edge, start fast but cannot do everything a full Node runtime can, including arbitrary npm packages with native bindings. Functions, running on Lambda, can do all of that, at the cost of the cold start Lambda has always had. Teams end up choosing per route: Edge Functions for the path that needs speed and can live within the constraints, Lambda Functions for the one that needs a library Edge Functions will not run.
Cloudflare's Workers isolates sidestep the classic cold-start problem almost entirely, since an isolate is far lighter weight than a Lambda container and the runtime is built around spinning many of them up cheaply. The tradeoff is the same one Netlify's Edge Functions make: the restricted runtime does not give an arbitrary Node environment. Cloudflare's newer container product exists specifically to close that gap, but it is a different, newer surface with a shorter production track record than either Lambda or Workers themselves.
Where Cloudflare's model breaks down
It is tempting, after the bandwidth math, to conclude Cloudflare Pages is the obvious choice. That undersells two real limitations.
First, 'no egress fee' only covers the CDN and Workers request layer. The moment an application needs object storage, a key-value store, or a SQL-like database at the edge, it is using R2, KV, or D1, each metered on its own terms: read operations, write operations, storage class. An application that is genuinely bandwidth-heavy but storage-light benefits enormously from the model. An application that is storage- or database-heavy will find those costs show up somewhere else on the invoice, just not on the bandwidth line.
Second, Workers impose a CPU-time ceiling per invocation. That ceiling is generous for the median web request, such as rendering a page, calling an API, or transforming a response, and a real constraint for anything doing heavy computation inside a single request, such as image processing or a large in-memory transformation. The container runtime exists for exactly this case, but it is newer than the isolate model it supplements, with a shorter track record in production.
None of that erases the bandwidth advantage. It does mean the honest comparison is not 'Cloudflare is cheaper' — it is that Cloudflare moves cost away from the line item most likely to surprise a team, toward line items that are more predictable for a mostly-content workload and less favourable for one that leans on compute-heavy or storage-heavy operations at the edge.
A framework for picking based on your actual traffic shape
The useful version of this comparison is not a scorecard. It is matching a platform's cost model to the shape of traffic an application actually gets.
An application whose traffic is public, spiky, and unpredictable, such as a content site or a marketing page that might get linked from somewhere large, has the most to gain from Cloudflare's no-egress model, because it removes the single largest source of bill shock for that traffic pattern.
An application built deeply around Next.js, with predictable enterprise or authenticated traffic and heavy use of image optimisation or incremental static regeneration, still gets real value from Vercel's framework-level integration. Fluid Compute's Active CPU billing has also closed a meaningful part of the cost gap that used to be the main argument for migrating away once traffic grew.
An application that wants to stay framework-agnostic, keep its options open, and is not yet at a traffic volume where bandwidth costs matter much either way, gets a pragmatic default in Netlify's free tier and split-runtime flexibility, accepting the Lambda cold-start tax as the price of that flexibility.
None of these are permanent choices. All three platforms are still actively rewriting their pricing models, sometimes more than once a year, which is itself worth pricing in before signing a longer commitment.
There is a fourth scenario worth naming separately: an internal tool or low-traffic admin panel, where none of this matters yet. At a few thousand requests a month, all three platforms are effectively free, and the deciding factor is genuinely the features table this article started by dismissing — whichever one the team already knows, or whichever one plugs into the rest of the stack with the least friction. The pricing model only becomes the deciding factor once traffic gets large enough, or unpredictable enough, for the differences in this article to show up on an actual invoice.
Model the bad day, not the average one
The three platforms are competing on something none of their pricing pages state directly: what happens to the invoice on the one day traffic does not behave the way the average month suggested it would. That is a harder number to find than a features table, and it is the one that actually matters once an application has real, unpredictable users attached to it.
Before choosing, it is worth running the numbers for a bad day, not an average one: what 10x normal traffic would cost on each platform, where that cost would land on the bill, and what it would take, in engineering time, to turn on the mitigations that prevent it. That is a more honest comparison than anything a pricing calculator produces on its own.
Frequently asked questions
Related reading
AI credit pricing has three different exchange rates, and vendors don't publish any of them
Three SaaS vendors call it an 'AI credit.' Each one set a different, rarely published exchange rate back to real dollars, and that gap is where bill shock comes from.
X, Zoom, and Teams went down from one fibre cut. The transit layer doesn’t show up on most redundancy diagrams.
A severed Zayo fibre route took down X, Zoom, Reddit, and Teams within minutes. Anycast and multi-region failover were never the layer protecting against this.
AI coding tools for backend engineers: what the standard benchmarks miss
Most AI coding tool comparisons measure autocomplete and greenfield code generation. Backend engineers spend most of their time reading, debugging, and refactoring — a different workflow with a different ranking.