Every 2026 writeup about leaving Vercel starts with the bill and ends somewhere else entirely. The hosting invoice is the trigger — usage-based pricing that spikes unpredictably, bandwidth meters that punish success — but ask anyone who finished the migration and they will tell you the bill was the easy part. The hard part was the three Vercel primitives their Next.js app had quietly absorbed: Edge Config for runtime flags, ISR's on-demand revalidation for fresh content, and the AI Gateway for model calls.
Here is the verdict first: none of the three has a drop-in equivalent on a generic host, and each one has to be re-architected, not re-pointed. The table below is the whole migration in miniature — the rest of this post is the receipt for every row.
| Vercel primitive | What breaks on exit | Self-hosted replacement | Honest effort |
|---|---|---|---|
| Edge Config (now Global Config) | Sub-millisecond global flag/config reads with no-redeploy writes | Redis/Valkey KV plus a read-through cache and a refresh path | A day for the store, a week for the propagation semantics |
| ISR on-demand revalidation | Shared Data Cache invalidation via revalidatePath/revalidateTag | Standalone Next.js plus a Redis-backed cacheHandler and a signed revalidation route | Straightforward on one box; a real project past one instance |
| AI Gateway | One endpoint, zero-markup routing, budgets, failover, logs | Keep calling it from anywhere — or LiteLLM, or direct provider SDKs | Zero if you keep it; days to weeks if you re-platform it |
Notice the shape of the tax: it is not money, it is rework. And it falls hardest on the teams that did exactly what Vercel asked of them — leaned into the primitives that made the platform worth choosing.
Edge Config: the flag store with no twin
Edge Config is the primitive teams miss first, because it tends to sit in the hottest path in the app: middleware. Feature flags, redirect tables, kill switches, blocked-IP lists — data that is read on nearly every request and written a few times a week. Vercel's pitch is specific and numeric: reads complete within 15ms at P99, often under 1ms, served from the region closest to the user, with writes propagating globally and no redeploy required. Reads work in Middleware and Functions behind a read token; writes go through the API.
One naming note before the inventory: Edge Config was renamed to Global Config in 2026. The store itself is unchanged and existing projects needed no action, but every doc URL you memorized now redirects. If your migration runbook still says "Edge Config," update the runbook, not the architecture.
What breaks on exit is not the storage — any key-value store holds flags — it is the combination of three properties that no single self-hosted component gives you for free:
- Edge-local read latency without managing replication.
- Global write propagation without a deploy.
- A read path inside middleware, which on Vercel runs before your origin is even touched.
The standard rebuild is a Redis or Valkey instance standing in for the store, a thin read-through cache in the app for the hot keys, and a refresh path — polling on an interval, a webhook the writer calls, or both — standing in for the no-redeploy propagation. That is a day of work to stand up and a longer tail to get right: cache TTLs that match your old propagation expectations, stampede protection when a popular flag flips, and a story for what middleware does when the store is unreachable (Vercel's answer was "served from memory on the edge"; yours has to be written down).
The teams that underestimate this one are the teams whose flags only ever lived in the Vercel dashboard. Audit every get() call against the store before you move — the redirect table someone added during an incident two years ago is part of your migration surface whether it is documented or not.
ISR revalidation: the semantics that only work on one box
Incremental Static Regeneration is the Next.js feature most associated with Vercel, and on-demand revalidation — revalidatePath() and revalidateTag() — is the part that quietly depends on the platform. The API is framework code; the cache it invalidates is platform infrastructure. On Vercel, the Data Cache is shared, so invalidating a tag invalidates it everywhere. On a self-hosted standalone server, the default cache is per-instance: filesystem and memory local to that process.
That distinction is invisible at one replica and load-bearing at two. Run two Next.js instances behind a load balancer with the default cache, fire a revalidation webhook, and the balancer routes it to one instance. Its sibling keeps serving the stale page until time-based revalidate expires it — or forever, for purely on-demand paths. This is one of the most reported "works on Vercel, broken on my VPS" failure modes in self-hosting writeups, and it has nothing to do with your code. Your code is correct; your cache topology changed underneath it.
The rebuild has three parts, all well-trodden:
- Run Next.js in standalone output mode (
output: "standalone"), the deployment unit self-hosting guides standardize on. - Add a shared cache handler. The
cacheHandleroption innext.configlets the Data Cache live in Redis instead of local disk, so every instance reads and invalidates the same entries. The ecosystem here is mature:next-shared-cachefor Pages and App Router setups,nextjs-turbo-redis-cachefor demanding production environments, and handlers tracking Next 16's split between ISR caching and the neweruse cacheremote-cache directives. - Rebuild the revalidation webhook. On Vercel the CMS calls a URL and the platform handles fan-out. Self-hosted, you own the route — a
POST /api/revalidatethat checks a secret and callsrevalidateTag()— plus whatever your CMS needs to reach it (stable URL, auth, retries).
Budget this one by instance count, not page count. A single-box deploy with a Redis sidecar is a weekend project with a long history of success stories. A multi-region fleet that wants Vercel-grade invalidation latency is redesigning cache topology, and should be scoped that way from the start.
AI Gateway: the one you might not have to rebuild at all
The AI Gateway is the odd primitive out, and intellectual honesty requires saying so up front: leaving Vercel hosting does not force you to leave the AI Gateway. It is callable from any infrastructure — any server, cloud, or laptop — with an API key, and Vercel documents exactly that. If your migration goal is cheaper compute or owned machines rather than vendor independence, the cheapest correct move is to keep the Gateway and change nothing about your model calls.
That said, teams leave platforms for independence too, and the Gateway accumulates the same quiet coupling as the other two. What it centralizes is considerable: one OpenAI-compatible endpoint across providers, zero markup over provider token prices, Bring Your Own Key with fallback to system credentials, per-team and per-key spend budgets (with soft-cap semantics worth reading closely), per-request logs recording model, provider attempts, latency, tokens, and cost, plus ordered provider and model fallbacks and routing rules. It has reached general availability with coding-agent and framework integrations attached, which means new apps adopt it almost by default.
If full independence is the goal, the exits rank cleanly by effort:
- Keep the Gateway, move the app. Zero model-layer work. You still have one vendor relationship, but it is a metered API relationship, not a hosting one.
- Self-host LiteLLM. The closest open-source analogue: one OpenAI-compatible proxy across providers, with budgets, logging, and fallbacks you operate yourself. Days of work plus ongoing ownership of the proxy.
- Call providers directly. Swap the Gateway client for provider SDKs or direct REST calls. Simplest to reason about, but every feature the Gateway centralized — failover, budgets, unified logs — becomes code you write or ops you accept losing.
The honest version of this section is that most teams should pick the first option and revisit it later. The Gateway's lock-in is the softest of the three precisely because Vercel built it to be called from anywhere — which also makes it the best model for what the other two primitives could have been.
The honest math: when the tax is worth paying
None of the above is an argument against leaving. The migration writeups converge for a reason: at sustained scale, self-hosting Next.js typically lands at a fraction of usage-based platform pricing — one careful 2025 accounting put it at 3–5x cheaper, with 50 million requests a month costing roughly $1,000+ on Vercel against $250–400 on raw AWS Lambda — and the gap widens once bandwidth and seat pricing enter the picture. Teams also leave for compliance, data residency, VPC integration, and the simple desire to own their infrastructure. Those are all good reasons, and the rebuilds above are all tractable.
They are also all real work, which is the actual thesis of this post. "Just point your git repo somewhere else" undersells the migration for any app that used what made Vercel worth choosing — which, if the platform did its job, is your app. So scope the exit with the primitives, not the pages:
- Inventory first. Every Edge Config read, every
revalidateTag/revalidatePathcall, every model call routed through the Gateway. Grep is faster than regret. - Sequence by blast radius. Flags and revalidation touch every request; the model layer usually touches one feature. Migrate in that order.
- Price the tail, not the setup. Standing up Redis takes an afternoon; matching no-redeploy propagation and shared invalidation semantics takes the sprint.
- Decide what "done" means for the Gateway. Keeping it is a legitimate steady state, not a halfway migration — write the decision down either way.
Stay on Vercel when iteration speed dominates and the usage bill fits inside your margins; the zero-config deploy pipeline, preview environments, and instant Next.js feature support remain genuinely hard to replicate. Leave when the meter, the compliance questionnaire, or the control plane says so — and when you do, bring this inventory. The teams surprised by the migration tax are the teams that priced the hosting and forgot the primitives.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.



