Skip to content
Docs

How to migrate from Render to Vercel

Migrate from Render to Vercel: map web services, cron jobs, and containers to their equivalents, and handle what doesn't move.

Ben SabicContent Engineer

To migrate from Render to Vercel, move any data off persistent disks, let framework detection deploy services built on a supported framework, add a Dockerfile.vercel for the rest, set the PORT environment variable in project settings, and recreate your environment variables and cron jobs. Background workers stay behind or get restructured.

This guide maps each Render concept to its Vercel equivalent, walks the migration in seven steps, and states plainly what has no equivalent.

Copy link to headingShould your app move?

Render builds services from native language runtimes, from Dockerfiles, and from prebuilt Docker images. All three paths can land on Vercel, but the service itself has to fit. Three questions settle it:

  1. Does it answer HTTP requests? Vercel Functions running container images are expected to open an HTTP server. Web services fit. Background workers and other always-on processes that never receive a request don't.
  2. Does it write to an attached disk? Render persistent disks have no Vercel equivalent. The data has to move to a managed database, cache, or blob store before the service does.
  3. Can it shut down in 30 seconds? On Vercel, a scaled-down container receives SIGTERM with a 30-second grace period. Render lets you stretch its shutdown delay to 300 seconds; Vercel does not.

If you answered yes to the first and third and can relocate any disk data, the migration is mechanical from here. If you're still weighing the platforms rather than planning the move, Running Docker on Vercel vs Render compares them directly; this guide assumes the decision has been made.

Copy link to headingHow do Render concepts map to Vercel?

On RenderOn Vercel
Web service on a native runtime (Build Command and Start Command)Framework detection deploys Express, FastAPI, Django, Go, and many others with minimal configuration
Web service on the Docker runtimeA Dockerfile.vercel at the project root, built and pushed to Vercel Container Registry during the build
Web service from a prebuilt imageThe Dockerfile that produces that image, added as Dockerfile.vercel; Vercel builds and pushes the image itself during the build step
Private serviceA service under the services key in vercel.json, internal by default
Cron jobA cron job in vercel.json, triggered by an HTTP GET to your chosen path
Background workerNo equivalent; restructure around HTTP and cron, or keep it on Render
Persistent diskNo equivalent; move data to a managed database, cache, or blob store first
Environment variablesEnvironment variables in project settings, with sensitive values supported
PORT (defaults to 10000)Traffic goes to port 80 unless you set PORT in project settings
Blueprints (render.yaml)The services key plus rewrites in vercel.json
Pre-deploy commandNo equivalent; run migrations from CI
Health check pathNo equivalent; validate on a preview deployment

Containers deployed this way run as Vercel Functions on Fluid compute with Active CPU pricing: you're billed for CPU when your code actively runs, not while it waits on I/O.

Copy link to headingMigration steps

Copy link to heading1. Inventory your Render services

List every service and note its type: web service, private service, background worker, or cron job. For each one, record the runtime (native, Docker, or prebuilt image), any attached disk, the health check path, the pre-deploy command, and any PORT override. Web services and cron jobs move directly. Background workers and disk-backed services need a decision first; see "What doesn't map from Render" below.

Copy link to heading2. Move data off persistent disks

Vercel has no persistent disk, so anything your service writes to an attached disk needs a new home before you migrate: a managed database, a cache, or blob storage. Backing services like these are available through the Vercel Marketplace. Do this step first, since it's the one most likely to require code changes.

Copy link to heading3. Check framework detection before writing any config

If your Render service uses a native runtime with a Build Command and a Start Command, such as npm install and npm start, you may not need a container at all. Vercel deploys a long list of frameworks with minimal configuration, including Express, Fastify, NestJS, Koa, Hono, FastAPI, Flask, Django, Go, Next.js, Nuxt, SvelteKit, and Astro. Reach for a container when detection doesn't apply: a backend in a language or runtime outside the list, system libraries such as FFmpeg or Chromium, a framework Vercel doesn't detect, or a need for identical behavior across environments.

Copy link to heading4. Add a Dockerfile.vercel where you need a container

Place a Dockerfile.vercel (or Containerfile.vercel) at the root of the project. Vercel detects the file automatically and adds a rewrite that routes all traffic to the container image; during the build step, the image is built and pushed to Vercel Container Registry. If your Render service deploys from a prebuilt image, start from the Dockerfile that produces that image, because Vercel builds and pushes the image itself as part of the build.

Copy link to heading5. Set the port and environment variables

On Render, your server binds host 0.0.0.0 and the PORT environment variable defaults to 10000. On Vercel, the container must open an HTTP server, and traffic goes to port 80 unless you set PORT in the project settings. If your server already reads PORT from the environment, set that variable in project settings and you're done. An ENV PORT line in the Dockerfile does not control Vercel's routing; only the project setting does.

While you're in project settings, recreate the remaining Render environment variables. Sensitive values are supported, so credentials move here too.

Copy link to heading6. Recreate cron jobs and multi-service wiring

Render cron job services become Vercel cron jobs declared in vercel.json. Vercel triggers each one with an HTTP GET request to the configured path on your production deployment, so the job's logic becomes an HTTP handler. Requests carry the vercel-cron/1.0 user agent, and the timezone is always UTC.

If a Render Blueprint runs several services together, declare them with services in vercel.json, each with its own root. Services are internal by default; a top-level rewrite with a service destination is what exposes one to the internet. For a service you want built as a container image, set runtime to container and entrypoint to the Dockerfile path relative to the service root:

{
"services": {
"web": {
"root": "web/"
},
"api": {
"root": "api/",
"runtime": "container",
"entrypoint": "Dockerfile.vercel"
}
},
"rewrites": [
{ "source": "/api/(.*)", "destination": { "service": "api" } },
{ "source": "/(.*)", "destination": { "service": "web" } }
]
}

Render private services that only other services call map to bindings: the calling service declares a binding, and Vercel injects the target service's URL as an environment variable, so services reach each other without hardcoded URLs and without a public route.

Copy link to heading7. Run it locally, deploy, and validate on a preview

vercel dev runs your container locally; it requires the docker CLI and a running Docker daemon. With services configured, vercel dev runs all of them together. Then push a commit: every commit gets an immutable preview deployment with its own URL. Check the port wiring, the cron handler, and the service routing on the preview before sending production traffic. This is also the moment to move anything that lived in Render's pre-deploy command, such as database migrations, into your CI pipeline.

Copy link to headingWhat doesn't map from Render

Persistent disks. There is no equivalent on Vercel. Move the data to a managed database, cache, or blob store from the Vercel Marketplace before migrating the service.

Background workers and always-on processes. Vercel's model is request-driven, so a process that runs around the clock without receiving requests doesn't fit. Restructure the work around HTTP endpoints and cron jobs, or keep the worker on Render and split the system across both platforms.

The pre-deploy command. No hook runs between the build finishing and the deployment going live on Vercel. Run database migrations and similar release tasks from CI instead.

The health check path. The container image docs define no health-check configuration. Validate each deployment on its preview URL before it serves production traffic.

Secure Compute and Static IPs. Neither is supported with custom container images yet, and the standard Vercel Functions limits apply. If your Render service reaches a database through an IP allowlist, plan around this before moving.

Configurable shutdown. Render sends SIGTERM 60 seconds after cutover and SIGKILL if the process outlives the shutdown delay, which defaults to 30 seconds and is configurable up to 300 via maxShutdownDelaySeconds. On Vercel, a function with no production traffic for 5 minutes (30 seconds in preview) scales down, and the container receives SIGTERM with a fixed 30-second grace period. Cleanup work has to finish within those 30 seconds.

Copy link to headingFrequently asked questions

Copy link to headingDo I need to change my Dockerfile to move from Render to Vercel?

Usually not, beyond naming: Vercel detects a Dockerfile.vercel or Containerfile.vercel at the project root, so rename or copy your existing Dockerfile. The main difference is the port: Render sets the PORT environment variable to 10000 by default, while Vercel routes traffic to port 80 unless you set PORT in project settings. If your server reads PORT from its environment, it runs on both platforms without a Dockerfile change. An ENV PORT line in a Dockerfile does not control Vercel routing; set the variable in project settings instead.

Copy link to headingWhat replaces Render's pre-deploy command?

Nothing directly: Vercel has no hook that runs between the build finishing and the deployment going live. Move database migrations and similar release tasks into your CI pipeline so they run before the new deployment takes traffic. Render's pre-deploy command already executes on a separate instance from your running service, so tasks written for it tend to port to CI without changes.

Copy link to headingCan I move my Render background workers to Vercel?

No. Render background workers can't move to Vercel as they are: Vercel's model is request-driven, so a worker that runs around the clock pulling jobs from a queue has no equivalent. Restructure the work around HTTP endpoints and cron jobs, or keep the worker on Render and run the two platforms side by side.

Copy link to headingCan I keep using render.yaml?

No. Vercel does not read render.yaml, so Blueprint definitions need translating. A multi-service Blueprint maps to the services key in vercel.json, with top-level rewrites deciding which paths reach each service, and cron schedules are declared in vercel.json as well. Environment variables move into project settings.

Copy link to headingDoes Render's health check path map to Vercel?

No. Vercel's container image documentation defines no health-check path configuration. Validate each change on its preview deployment instead, before the change reaches production traffic.

More Vercel Services guides