The actual six hours
- 08:14Coffee.
npm i -g wrangler. Cloudflare account already existed from a side project. ~12 min.
- 08:26Adapted Next.js app to
@opennextjs/cloudflare. One config tweak, one runtime export per route. ~58 min.
- 09:24Postgres dump from Vercel via
pg_dump. Restored to a fresh Supabase project. Same Postgres flavor, zero schema drift. ~41 min.
- 10:05Auth.js → Supabase Auth. This was the only painful part. Two hours of session-cookie debugging because I forgot the JWT secret had to match the old issuer.
- 12:18Migrated 4.2 GB of user uploads from Vercel Blob to R2 with a shell loop. Cloudflare egress to R2 was free.
- 13:30Resend already in place. Just swapped the API key and pointed the SPF/DKIM at the same verified domain.
- 14:11DNS flip. Cut over with a 60-second TTL window. Zero user-reported errors in Sentry.
- 14:28Deleted the Vercel project. Slightly emotional moment. Closed laptop.
The OpenNext adapter for Cloudflare did most of the heavy lifting. Two years ago this would have been a fortnight of yak shaving. In 2026 it’s an evening.
The one config that broke me
If you’re following along, the gotcha was middleware. Vercel’s middleware runs at the edge. Workers run everything at the edge by default. So my old middleware-gated routes were getting double-handled until I deleted the file outright. The runtime declaration that finally made it work:
// next.config.ts
import { setupDevPlatform } from '@opennextjs/cloudflare/dev'
if (process.env.NODE_ENV === 'development') {
await setupDevPlatform()
}
export default {
experimental: {
runtime: 'edge',
serverComponentsExternalPackages: ['@supabase/supabase-js'],
},
images: { unoptimized: true }, // Workers handles this via R2 + cf-image-resizing
}
Note the images: { unoptimized: true }. Vercel’s image optimization is a known billing trap (the deploywise.dev case study I’ll embed below shows a $20 plan ballooning to $286). Cloudflare’s image resizing is included with your Workers traffic at no marginal cost up to 5,000 unique transformations per month on the free tier. Plenty for me.
What the new bill actually looks like
38K
Daily Worker requests (cap: 100K)
217 MB
Postgres size (cap: 500 MB)
4.2 GB
R2 stored (cap: 10 GB-month)
The math, three weeks in: I haven’t paid a cent. I came within 22% of the Cloudflare daily request cap once during a HackerNews mention, and Cloudflare let me through anyway because their throttling is a 429 not a hard wall — it just degrades. A paid Workers plan kicks in at $5/mo if I cross 10M requests in a month, which I won’t.
$0.00
First three-week invoice on the new stack
Source: my Cloudflare + Supabase + Resend dashboards, May 2026
The blind spots
Three things I didn’t test, in case you’re tempted:
- I didn’t load-test past 100K req/day. My traffic is steady. If you spike, you’ll need a paid Workers plan or a queue layer. The bill stays small but it isn’t zero.
- I didn’t migrate ISR pages. The OpenNext adapter supports it now but I rebuilt my few cached pages as Worker static routes. Cleaner. Your mileage will differ.
- I didn’t run this on Windows. I can’t be bothered. Wrangler on WSL works fine from what I’ve read, but I’m a Mac person, sorry.
The pricing structure now emphasizes flexibility with the credit system while adding more paid add-ons for advanced features that were previously enterprise-only.
Vendr’s 2026 Vercel pricing summary — read “flexibility” as “unpredictability”
Who should not do this
If you’re a 12-engineer team shipping 40 PR previews a day with shared environments and SSO, Vercel earns its keep. The preview infra alone is a quarter of an engineer’s time. Don’t migrate.
If you’re a solo dev paying $300/month because you set things up two years ago and never looked again — spend the Saturday. Worst case you go back. Vercel’s import tool reads a Cloudflare project and restores in 15 minutes. The exit is symmetric.
What happens next
Vercel knows. The September 2025 repricing was their first acknowledgement that Pro had drifted upmarket. The February Turbo-by-default move was the second. I’d bet on a $5 “Indie” tier landing by AI Engineer SF this June — capped resources, predictable bill, designed exactly for the migration I just did so they can keep the long tail from defecting. If it lands, I might even come back. The credit system, though? That has to die for me to mean it.
Until then, my Saturday saved me $3,749 a year. I’ll take it.