Next.js on Cloudflare vs. Vercel: Why Pretty Deploys Don’t Scale

What I learned moving a full Next.js app from Vercel to Cloudflare and why I’m not going back

I didn’t plan to switch.

My Next.js app was living happily on Vercel. It was fast, easy to deploy, and honestly? It just worked. But like every relationship in tech, comfort slowly gave way to irritation: random cold starts, pricing that scaled faster than my app did, and build times that felt like waiting in a loading screen without the background music.

So I started looking around.

Cloudflare Pages + Workers had always been on my radar, but I assumed it was too raw or too weird for a full-on Next.js deployment. Turns out, it’s more powerful and more stable than I expected. And cheap. Like absurdly cheap.

This post is not some “Vercel bad, Cloudflare good” rant. It’s just what happened when a dev like me finally said: what if I actually moved this thing?

Spoiler: It wasn’t painless. But it was worth it.
Here’s how it went.

Press enter or click to view image in full size

Table of contents

  1. Why I started with Vercel
  2. The breaking point
  3. Why Cloudflare caught my eye
  4. What the migration actually involved
  5. How the app performs now
  6. Things I still miss from Vercel
  7. Should you switch?
  8. Bonus resources

Press enter or click to view image in full size

Why I started with Vercel

If you’re building a Next.js app, picking Vercel is kind of like choosing VS Code. It’s just… the thing you do.

Back when I started this project, I wasn’t looking for clever. I wanted smooth builds, auto previews, dead-simple deploys, and no server maintenance. Vercel delivered all that right out of the box.

My stack looked pretty standard:

  • Next.js (app router)
  • Tailwind for styling
  • A few API routes (for basic auth + backend glue)
  • MongoDB Atlas for the DB
  • Some client-only Firebase stuff
  • No custom server just SSR, ISR, and static pages

On Vercel, deploying was brainless. Push to main, preview URLs popped up. SSR worked seamlessly. Edge functions? Magic. Logs? Click and done. Even the CLI felt like Apple-level design minimal but slick.

For a solo dev or a small team, Vercel is honestly great… until it isn’t.

Because here’s the thing: the more my app grew, the more Vercel started acting like it wasn’t built for me anymore. Costs crept up. Builds got slower. And I started hitting limits I didn’t even know existed until they slapped me in a production error message.

That’s when the cracks began to show.

The breaking point

At first, the issues were just annoyances.

A cold start here. A longer build there. Maybe a few limits I could work around with a hack or a plugin. But over time, the tiny paper cuts turned into a full-on dev experience papercut apocalypse.

Here’s what finally pushed me over the edge:

  • Cold starts on edge functions started to get bad. Like “wait three seconds before anything happens” bad.

  • Build times ballooned from under 2 minutes to over 6, especially after adding image optimizations and API routes.

  • Preview deployments kept failing, especially when hitting the free-tier function limits (which aren’t obvious until they hit you).

  • Pricing scaled aggressively. $20/month turned into $80 with minimal traffic, and I still wasn’t using most features.

One day, a deploy failed silently again because of an internal limit I wasn’t aware of and that’s when I snapped. I wasn’t building a startup, just a moderately useful app with some traffic and SSR. It didn’t feel fair.

And it sure didn’t feel cheap anymore.

Press enter or click to view image in full size

Why Cloudflare caught my eye

I didn’t wake up one day thinking, “Can’t wait to rebuild my hosting setup.” Like most devs, I started with a Google search that sounded something like:

“vercel alternative cheaper edge functions nextjs”

And to my surprise, Cloudflare Pages + Workers kept popping up not in the “hacker news hype” way, but in blog posts by indie devs who actually used it.

At first, I was skeptical. Cloudflare? The DNS guys? Aren’t they just for caching static files and annoying bot checks? But digging deeper, I saw they’d gone full edge runtime mode:

  • Cloudflare Pages handles static sites + build pipelines

  • Cloudflare Workers gives you edge functions (no cold starts)

  • KV, R2, D1 for key-value, object storage, and SQL like S3, but faster and cheaper

What sold me was this: Cloudflare wasn’t trying to be another Vercel clone. It was built around edge-first execution from the start, with performance that doesn’t punish you for being global.

Quick comparison: Vercel vs Cloudflare (for solo Next.js app)

Press enter or click to view image in full size

Cloudflare felt like that weirdly powerful open-source tool that quietly levels up while no one’s looking until suddenly, it does everything you need and costs almost nothing.

So I started testing.

What the migration actually involved

I expected pain and I wasn’t entirely wrong. But it was more “changing gear mid-race” than “total system meltdown.”

Here’s how I moved my Next.js app from Vercel to Cloudflare Pages + Workers.

1. Setting up Cloudflare Pages

Cloudflare lets you link a GitHub repo just like Vercel. I pointed it to main, chose “Next.js” as the framework, and it auto-detected the build command:

npm run build

But Cloudflare Pages builds on Pages Functions (via Workers), so I had to make sure output files and routing were Worker-compatible. That meant adding:

// package.json
"scripts": {
"build": "next build && next export"
}

If you’re using SSR, you’ll need a custom adapter or route via Workers directly. That’s where @cloudflare/next-on-pages comes in:

npm install -D @cloudflare/next-on-pages wrangler

2. Creating wrangler.toml

This file tells Cloudflare how to run your app. Mine looked like this:

name = "my-nextjs-app"
compatibility_date = "2025-07-01"
pages_build_output_dir = ".vercel/output/static"

This config allows you to route edge functions and API routes through Workers seamlessly. The Docs for this are way better than expected:
🔗 Cloudflare Next.js guide

3. Fixing middleware and API routes

Vercel’s edge middleware uses their own runtime, which doesn’t 100% match Cloudflare’s Workers runtime.

I had to rewrite a few things:

  • next-auth token validation middleware → replaced with a lightweight JWT verifier

  • req.nextUrl → replaced with standard URL parsing

  • Logging middleware → had to polyfill console.log behavior for Workers (they buffer logs slightly differently)

4. Image optimization ≠ automatic

Vercel’s next/image integration Just Works™. On Cloudflare, I had to:

  • Use @cloudflare/next-on-pages for image serving OR
  • Manually use Cloudflare Images / CDN caching

There’s no plug-and-play alternative (yet), so plan on handling image paths and cache headers yourself.

5. Deploy, test, fix, repeat

The first deploy failed. Then the second one half-worked. By the third deploy, I had everything running just with a few console errors and one broken redirect.

What helped:

  • Cloudflare logs from the Pages UI (functional, not fancy)
  • Wrangler CLI to test locally
  • A test subdomain (so I didn’t break prod while debugging headers)

Things I still miss from Vercel

No setup is perfect, and Cloudflare while fast and cheap isn’t as polished in every way. Vercel definitely spoiled me in a few areas.

Here’s what I lowkey miss:

1. Instant preview deployments

Vercel’s preview URLs are buttery smooth. Every branch, every PR, auto-deployed with context-aware links in GitHub. Cloudflare has something similar, but it’s less elegant, and not always tied to commits in the same magical way.

2. The CLI experience

Vercel CLI feels like a developer’s dream. One command, instant deploys, link to the dashboard, all cleanly formatted.
wrangler works but it’s clearly built by and for people who enjoy reading docs on vacation.

3. Built-in image optimization

next/image on Vercel just works. Cloudflare can do it but you have to wire things up manually or use separate services. That means more config, more CDN headers, and more time I’d rather spend writing bad code.

4. That polished UI

Vercel’s dashboard is smooth. Logs are searchable, builds are detailed, everything is just a few clicks away. Cloudflare’s UI isn’t bad it’s just more functional and less “designed to impress your boss during a Zoom demo.”

But honestly? These are minor UX tradeoffs. For the core dev experience fast builds, no cold starts, and no pricing anxiety I haven’t looked back.

Cloudflare feels like switching from a MacBook to a custom-built Linux machine that runs 2x faster and costs 90% less. Less shiny, more power.

Should you switch?

If you’re expecting some definitive “Cloudflare wins” mic drop… this isn’t that.

The truth is, it depends on what kind of dev you are.

You should consider switching if:

  • You’re a solo dev or indie hacker watching every dollar
  • You’re building something that needs fast global edge delivery
  • You like having full control over your platform and build process
  • You don’t mind tweaking a few configs to get extra speed and flexibility

You might want to stay on Vercel if:

  • Your team already uses it across projects
  • You rely heavily on next/image or other platform-locked features
  • You don’t want to spend time on custom routing, logging, or deploy tweaks
  • You value UI polish, previews, and a smoother “works out of the box” experience

My take?

Cloudflare feels like the underdog that quietly became the boss fight. It’s not trying to be trendy it’s just stupid fast, extremely cheap, and surprisingly capable.

For most solo or small-team devs, the switch is worth it. For bigger teams? Maybe wait a bit. But keep it on your radar.

Because this platform’s moving fast and it’s doing it at the edge.

Bonus resources

If you’re thinking about making the move, here’s everything that helped me survive the migration (and avoid screaming into the deploy logs):

Templates & Tools

Dev communities & help

Final thoughts

Vercel is great until it isn’t. Cloudflare’s confusing until it clicks.
I didn’t expect to like Pages + Workers this much but now that it’s running, it’s hard to justify going back.

This isn’t a Cloudflare ad. It’s just one dev’s journey from expensive and easy… to fast and free.

And if you’re like me always tweaking, always optimizing, and always wondering “could this be better?” maybe it’s time to give it a shot.

Similar Posts