Migration guide · From Vercel
Migrate from Vercel to SIAX
Vercel is built for getting started fast, and it does that well. The pain comes later: per-seat pricing across the team, bandwidth billing that's hard to predict before the month is over, function invocations charged per call, and a platform where you can neither inspect how something is built nor move it without rewriting parts of the app.
With us you run the same app as a container on App Hosting, with a fixed monthly cost and a database you can connect to with psql. Everything under the hood is open source and all data sits in the EU. What you don't get is Vercel's global edge network. It's worth saying plainly: if your audience is in Southeast Asia and you're measuring TTFB in tens of milliseconds, we're the wrong choice.
The guide is based on a Next.js app since that's the most common case. The pattern is the same for Remix, Astro, SvelteKit and Nuxt. The difference lies in how much of Vercel's platform features have crept into your code.
Time required
Half a day for an app that's just an app. One to two weeks if you lean on ISR, Edge Middleware, Vercel Blob or KV.
Downtime
None for the app if you run in parallel during the DNS switch. The database move requires a write freeze: minutes for a small database, longer if you don't set up logical replication.
How to do it
- 1
Inventory what you actually use from Vercel
Search the code for what only exists at Vercel: Edge Middleware, runtime = edge, request.geo, waitUntil, ISR with on-demand revalidation, Vercel Cron, Blob, KV and Postgres. Write down every hit. That list is the entire difficulty of the migration; the rest is routine. Zero hits means a couple of hours of work.
- 2
Build the app as a container
Set output to standalone in next.config and write a two-stage Dockerfile: build with devDependencies, run with a slimmed-down node-alpine image. Verify the app starts locally with the same environment variables as in production. Check that sharp is included if you use next/image, otherwise image optimization falls back to unpaid CPU on every cold start.
- 3
Replace the Vercel-specific features
Edge Middleware runs with us as regular Node middleware in the app, not on the edge. Geo and IP fields from Vercel don't exist and must be replaced with headers from our proxy or a GeoIP database you run yourself. Vercel Cron is replaced with a scheduled job in CI or a cron inside the container. Blob is swapped for our object storage via the S3 API, which is a real code change, not a configuration line.
- 4
Move the database and storage
Provision Managed Postgres and run a pg_dump followed by pg_restore against the new instance. Check that all extensions are present before you start, not afterward. For larger databases, set up logical replication, let it catch up, and then switch the connection string during a brief write freeze. Files in Vercel Blob are copied with rclone against our S3 endpoint.
- 5
Set up build and deploy
Connect the repo to Git and CI and let a pipeline build the image and deploy on push to main. Put all environment variables in the secrets manager, never in the image. While you're at it, rotate the keys that sat in Vercel's project settings, since you're exporting them anyway.
- 6
Run in parallel and compare
Let the new environment sit behind a staging subdomain while Vercel keeps taking production traffic. Compare response times, cache headers, redirects and 404 behavior page by page. Check in particular that pages you thought were static are actually rendered statically, and that the cache doesn't go empty on every deploy.
- 7
Switch DNS and decommission
Lower the TTL to 60 seconds a day in advance, then switch the A or CNAME record. Keep the Vercel project around for a couple of weeks as a fallback and to catch any hardcoded vercel.app URLs. Only then cancel the subscription.
What's actually tricky
- ISR works self-hosted, but the cache is per instance. Run more than one instance and users get different versions of the same page until you point to a shared cache handler in Next.js. The simplest path is to start with one instance.
- Edge Middleware becomes Node middleware. The latency profile changes, and anything that relied on Vercel's geo or country fields must be replaced or removed.
- Per-commit previews aren't built in. You get prod, staging and dev environments and can build branch deploys in CI, but a unique URL per pull request is something you have to set up yourself.
- Vercel KV has no equivalent with us. Need a key-value cache? Run Redis or Valkey on a VPS and you own updates and backup yourself.
- Our network is EU-regional, not global. For a Nordic or European audience the difference is marginal. For a global audience with hard latency requirements it isn't.
Cost example
A small production app with staging, one Postgres and 100 GB of files: App Hosting from 99 kr, staging environment 49 kr, Managed Postgres from 89 kr and object storage 25 kr, so roughly 262 kr per month excluding VAT. Larger instances cost more. The equivalent at Vercel with three developers on Pro plus a managed Postgres lands around 1,000 to 1,500 kr per month before bandwidth and function overage, and their prices change continuously.
Frequently asked questions
- Does Next.js work fully with you?
- Yes, in Node mode with standalone output. What doesn't come along are the surrounding platform features: edge runtime, Vercel's geo headers, Blob, KV and Cron. The app works, but those calls need to be rewritten.
- Do you have a CDN in front of the app?
- We cache static assets and can put a cache in front of pages, but we don't have hundreds of PoPs around the world. Our regions are Helsinki, Falkenstein and Nuremberg. For Nordic visitors the latency is comparable to Vercel; for visitors in Asia or South America it isn't.
- Are you ISO 27001 or SOC 2 certified?
- No. We have neither ISO 27001 nor SOC 2. What we do have is GDPR compliance, data processing agreements, all data in the EU, and a stack built on open source that you can audit. If your customer contract requires a certification, that's a real blocker and we'd rather say so upfront.
- What happens if we want to go back?
- The app is a container and the database is plain Postgres. You take a dump and carry on somewhere else. That's the practical meaning of us not building our own proprietary primitives.
