← All playbooks
Hosting migration

Vercel → Railway

Run the same repo on Railway as a long-running service. Vercel secrets cannot be read back, and the www redirect is not a Railway checkbox.

Typical timeline5 to 12 business days16 to 40 hours active work
Statusneeds review
Source profileVercel environment variable docs reviewed 2026-11-02
Destination profileRailway variables, domains, and public networking docs reviewed 2026-11-02
Documentation date
Review window
Evidence6 sources
This route needs review.Use it as a planning baseline, then verify the dated sources and test with representative data before production.
Before you migrate

Should you make this move?

Both platforms have a case. Compare what you gain with what you give up before scheduling the cutover.

Current platform

Vercel

Reasons to stay
  • Exceptional frontend previews and framework integration make releases fast and polished
  • Managed deployments reduce infrastructure and release-management work
Reasons to leave
  • Costs and proprietary platform features can grow rapidly with traffic and complexity
  • Runtime assumptions, platform services, and pricing models shape the architecture
New platform

Railway

What gets better
  • Fast service and database provisioning gives developers a low-friction application platform
  • Managed deployments reduce infrastructure and release-management work
What gets worse
  • Usage pricing and infrastructure abstraction can become limiting at scale
  • Runtime assumptions, platform services, and pricing models shape the architecture
Best of the move

Railway: Fast service and database provisioning gives developers a low-friction application platform. This removes a major source-side concern: Costs and proprietary platform features can grow rapidly with traffic and complexity.

Worst of the move

What you lose: Exceptional frontend previews and framework integration make releases fast and polished. What you inherit: Usage pricing and infrastructure abstraction can become limiting at scale.

Jump to a section
01At a glance

Know the shape of the move.

Transfer outcome12 features audited
Transfer outcome distributionClean transfer: 1, Partial transfer: 4, Manual rebuild: 5, Not transferred: 2.
Clean1
Partial4
Manual5
Lost2
Mapping route9 of 10 fields have a destination path

This timeline assumes

  • One production service, with preview and development values you can still name. The site already documents Vercel → Render, Vercel → Netlify, and Vercel → Cloudflare Pages.
  • The app can listen on a port. A Vercel-only adapter stays on Vercel until you change it.
  • You keep the Vercel project until Railway serves the domain and a rollback DNS record is written down.
  • Secrets marked Secret in Vercel are write-only after saving. You rotate anything you cannot read.
  • A database attached elsewhere, such as Neon, can stay where it is. This playbook moves the app, not that database.
02What transfers

What survives the move.

“Partial” and “manual” are not footnotes. They are work that must be scheduled and verified.

ItemOutcomeImpactWhat happensMitigation
The production commitcleancriticalYou deploy the same repository. Thilo Maier connected GitHub and Railway built the site. Railway does not import a Vercel deployment object.Record the production SHA and build that commit on Railway before you touch DNS.
A serverless adaptermanualcriticalVercel runs functions. Railway runs a service. Maier had to replace SvelteKit's adapter-vercel with adapter-node. Prerendering then failed on the Railway build until he changed how collections were loaded.Boot the app locally with the Node adapter and the same env file you will paste into Railway.
Config values you can still readpartialcriticalVercel splits variables into Config and Secret. Config stays readable to members with project access. Railway's RAW editor accepts a .env paste, and those variables are available during the build and at runtime.Pull development values with vercel env pull, then paste only the names that belong on the production service.
Secret valuesmanualcriticalVercel says Secret values are write-only after saving. You cannot open the dashboard and copy them onto Railway.Rotate each secret into Railway, then deploy. Vercel changes apply only to new deployments, so the old project keeps the old value until you redeploy it.
Production, Preview, and Development scopemanualhighA Vercel variable can target Production, Preview, a single git branch, Development, or a custom environment. Branch-specific preview values override other preview values with the same name. Railway applies the variables you deploy onto that service.Make one list per Vercel environment. Do not paste Preview-only values into the production service.
Browser-visible build variablespartialhighRailway says every service variable is present at build and at runtime. The framework prefix still decides what is bundled. Next.js uses NEXT_PUBLIC_. Vite uses VITE_. SvelteKit uses PUBLIC_. A build-time value is baked in, so a change needs a new Railway deploy.Search the Railway build log for a value that should have stayed on the server.
Vercel variable sizepartialmediumOn Node.js, Python, Ruby, and Go, Vercel allows 64 KB of environment variables combined per deployment. The edge runtime is 5 KB per variable. Railway's variable doc does not repeat those caps.If a value exists only because of an edge limit, decide whether the Railway process still needs it.
Custom domain and certificatemanualcriticalRailway gives you a CNAME and a TXT record. Both are required. If the TXT record is missing, the domain returns 404 after the CNAME resolves. Let's Encrypt certificates use ECDSA keys, last 90 days, and renew when 30 days remain. Issuance is expected within an hour and can be attempted for up to 72 hours.Add both records, wait for the green check, then request https on the hostname.
www to apexmanualhighRailway's Cloudflare recipe creates the www redirect as a Cloudflare Bulk Redirect, with status 301, after the apex domain is on Railway. Maier found no platform-level redirect and deployed a second small app to send www to the apex, because a SvelteKit handle hook does not run for prerendered pages.Pick one redirect, at the DNS host or in a second service, and request both hostnames.
Plain HTTP callspartialhighRailway redirects an HTTP GET on port 80 to HTTPS with a 301. An HTTP POST on port 80 is redirected and the method becomes GET. WebSocket connections are exempt from the idle timeouts that apply to ordinary HTTP.Point health checks and clients at https. A POST that still uses http will not arrive as a POST.
Old deployment historylostmediumVercel keeps previous deployments on the Vercel project. Railway starts a new service. Variable edits on Vercel do not rewrite old deployments.Keep the Vercel project through the rollback window so you can send the domain back.
Preview URLslostmediumA Vercel preview URL is not a Railway hostname. Railway can give the service a .railway.app domain from Public Networking, and that domain is a new name.Generate the Railway domain and smoke-test there before the custom domain moves.
03Field and feature mapping

Where each thing goes.

SourceDestinationMethodNotes
Production git commitRailway deploymentmanualBuild the SHA you recorded. Railway does not import a Vercel deployment.
adapter-vercel or a functions-only entryProcess that listens on a portmanualMaier switched SvelteKit to adapter-node before the Railway build was useful.
Config variableService variabletransformReadable in Vercel. Paste through Railway's RAW editor, then deploy the staged change.
Secret variableNew service variablemanualWrite-only on Vercel after save. Rotate it.
Preview or branch variableA non-production service, or nowheremanualDo not drop branch overrides into production.
NEXT_PUBLIC_, VITE_, or PUBLIC_ valueSame name on the Railway servicetransformStill inlined at build. Redeploy after a change.
vercel env pull fileRAW editor pastetransformThat file is the Development environment, not Production.
Custom domainRailway custom domainmanualCNAME and TXT. Missing TXT is a 404.
www redirect checkboxDNS-host redirect or a second servicemanualRailway's own Cloudflare notes put this redirect in Cloudflare.
Preview URL and old logsNo destinationunsupportedThey stay on the Vercel project.
04Before you begin

Make the move recoverable.

Backup procedure

Create the source-of-truth backup

Keep the Vercel project, the SHA, and a copy of every variable you can still read.

  1. Write down the production SHA, build command, and the domain that answers today.
  2. Run vercel env pull and save that file outside the repo.
  3. List Secret names you cannot read, and where the current value lives.
  4. Export the DNS records, including whatever sends www to the apex.
  5. Leave Vercel deployed.

Proof to capture: A note with the SHA, the env file, the secret names, and the DNS records you can put back.

Transformation · The framework's Node adapter and a Railway service

Service boot

Turn a Vercel build into a process Railway can run.

  1. Replace a Vercel-only adapter if the app does not already listen on a port.
  2. Build the production SHA with the public prefixes the framework expects.
  3. Open the generated Railway domain before any custom DNS change.
  4. If prerender or the build fails only on Railway, fix that on this SHA. Maier's local build hid a prerender failure.

Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.

Transformation · Railway variables and the domain panel

Domain and variables

Move traffic after secrets and both DNS records are in place.

  1. Paste readable variables, rotate the write-only ones, and deploy the staged change.
  2. Add the CNAME and the TXT record. Wait for the green check.
  3. Put the www redirect on the DNS host, or ship a second service the way Maier did.
  4. Call one production POST over https. An http POST will arrive as a GET.

Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.

05Handle with care

The things most likely to hurt.

These are operating limits. Treat every “Stop if” condition as a blocked migration, not a suggestion.

Configuration

A write-only secret is pasted as a blank

criticallikely likelihood

The Railway variable exists and the value is empty or still the development value from vercel env pull.

Consequence
Production calls the wrong API, or it fails closed after DNS moves.
Mitigation
Rotate every Secret and deploy before the domain changes.

Stop if: You cannot name the current production value of a secret the app needs.

Cutover

The domain verifies without the TXT record

criticalpossible likelihood

The CNAME resolves and the browser shows Railway's 404.

Consequence
The hostname does not reach the service, and a retry can look like an app bug.
Mitigation
Compare both records with the values Railway shows.

Stop if: The dashboard has no green check for the hostname you are about to announce.

Cutover

www still depends on Vercel

highlikely likelihood

The apex works on Railway and www still points at Vercel, or a handle hook misses prerendered pages.

Consequence
Half of the bookmarks hit the old project.
Mitigation
Request https on the apex and on www after the redirect is published.

Stop if: Either hostname still lands on Vercel when you meant to leave.

06Precise timeline

Do the work in this order.

Estimate forOne Vercel project with production and preview variables, a custom domain, and a www redirect
Total elapsed5 to 12 business days
Active work16 to 40 hours
BufferAdd time if the framework adapter or prerender step has to change, as it did for Maier's SvelteKit site.
01
Days 1 to 2Name every variable1 to 2 days
02
Days 2 to 3Save the Vercel side1 day
03
Days 3 to 8Boot on a Railway domain3 to 5 days
04
Days 8 to 10DNS1 to 2 days
05
Days 10 to 15Watch the old host3 to 5 days
  1. Days 1 to 2 · inventory

    Name every variable

    4 to 8 hours active1 to 2 days elapsedWhoever holds the secrets waiting
    • List Production, Preview, and Development names.
    • Mark write-only secrets.

    Depends on: Vercel project access

    Stop / go checkpoint

    Build on Railway?

    Go when: Every production name is either readable or assigned to a rotation.

    Stop when: A required secret has no owner.

  2. Days 2 to 3 · backup

    Save the Vercel side

    2 to 4 hours active1 day elapsedNone waiting
    • Record the SHA and DNS.
    • Run vercel env pull and store it outside git.

    Depends on: Inventory

    Stop / go checkpoint

    Change the app?

    Go when: You can put the current DNS back from the notes.

    Stop when: The production domain's records are unknown.

  3. Days 3 to 8 · pilot

    Boot on a Railway domain

    8 to 20 hours active3 to 5 days elapsedBuilds waiting
    • Switch the adapter if the app does not listen on a port.
    • Deploy variables and open the .railway.app host.
    • Fix build-only failures before DNS.

    Depends on: Saved env file

    Stop / go checkpoint

    Add the custom domain?

    Go when: The Railway hostname serves the production SHA.

    Stop when: The build only works on Vercel.

  4. Days 8 to 10 · cutover

    DNS

    2 to 5 hours active1 to 2 days elapsedCertificate issuance, up to 72 hours if it stalls waiting
    • Add CNAME and TXT.
    • Publish the www redirect.
    • Request apex, www, and one https POST.

    Depends on: Green check on the Railway domain

    Stop / go checkpoint

    Leave Vercel in place?

    Go when: Both hostnames hit Railway and the POST keeps its method.

    Stop when: The custom domain 404s or www still hits Vercel.

  5. Days 10 to 15 · observe

    Watch the old host

    2 to 4 hours active3 to 5 days elapsedDNS caches waiting
    • Keep Vercel deployed.
    • Check certificate renewal is not your problem yet. The first cert lasts 90 days.
    • Remove preview-only values that landed on the production service.

    Depends on: Domain on Railway

    Stop / go checkpoint

    Stop using Vercel for this app?

    Go when: A rollback DNS change is still written down and unused.

    Stop when: A secret or the www host still depends on Vercel.

07The point of change

Cut over with a way back.

Go live

Cutover

Serve the production host from Railway while Vercel can still take the domain back.

Recommended window: A low-traffic hour with DNS access and the previous records on paper.

  1. Deploy the approved SHA with rotated secrets.
  2. Confirm the .railway.app host.
  3. Add the CNAME and the TXT record and wait for the green check.
  4. Publish the www redirect off Railway's platform settings.
  5. Request the apex, www, and one POST over https.
  6. Leave the Vercel project deployed.

Proof to capture: Both hostnames answer from Railway, and the Vercel project is unchanged.

Return to safety

Rollback

Point the domain back at Vercel.

Deadline: Before you delete the Vercel project or rotate a secret only the old deployment can use.

  1. Restore the DNS records you saved, including www.
  2. Confirm Vercel still has the previous production deployment.
  3. Leave the Railway service up but off the public domain.
  4. Write down which variable or redirect failed.
  5. Fix that before the next attempt.

Proof to capture: The public host is the Vercel deployment again.

Rollback immediately when
  • Custom domain returns 404
  • www still or no longer hits the host you wanted
  • A POST over http arrived as a GET
  • A rotated secret does not match production
  • The Railway build is not the recorded SHA
08Verification report

Prove the migration worked.

Every blocking check must pass. Capture the evidence before cleanup begins.

0%
Interactive report preview0 / 8 checks passed
PassIDCheckMethodExpected resultEvidence
V-01BlockingProduction SHACompare the running Railway deployment with the SHA you recorded.They match.Deploy log.
V-02BlockingPort listenOpen the .railway.app URL.The app answers without a Vercel adapter error.HTTP check.
V-03BlockingReadable variablesCompare names in the Railway service with the Production list.Each production name is present or marked dropped.Name list.
V-04BlockingRotationCall one path that uses each rotated secret.The path succeeds with the new value.Call log.
V-05BlockingNo preview valuesRead the production service variables for known preview-only names.Those names are absent.Variable review.
V-06BlockingCNAME and TXTLook for the green check, then request https on the apex.The certificate is issued and the app loads.Dashboard check.
V-07Blockingwww and POSTRequest https://www and send one POST to https.www lands on the apex app. The POST stays a POST.Request notes.
V-08BlockingVercel still deployedOpen the Vercel project and the saved DNS notes.You can restore the previous records.DNS note.
09Post-migration cleanup

Remove the scaffolding safely.

Safe after: Several days of traffic on Railway, with www and the apex both correct, and the Vercel project still available.

  1. Store the env file and DNS notes with the migration record.
  2. Remove development-only values from the production service.
  3. Confirm the certificate shows as issued.
  4. Keep Vercel until you deliberately stop it.
  5. Update the runbook so the next person does not look for a Vercel redirect checkbox.
10Experiences from the field

When the plan met reality.

First-hand accounts are preferred. Vendor case studies are labeled, and every note below is an editorial paraphrase—follow the link for the full context.

First-person accountThilo Maier · maier.tech

It ain't easy to move a side project off Big Tech2025

Thilo Maier moved his own SvelteKit site, maier.tech, from Vercel to Railway on 7 November 2025. He replaced adapter-vercel with adapter-node, then found that prerendering which worked locally failed on the Railway build until he changed how posts and notes were loaded. Railway had no platform-level redirect from www to the apex, a SvelteKit handle hook did not run for prerendered pages, and he deployed a second small app to do that redirect.

What they recommend
  • Change a Vercel-only adapter and reproduce the production build on Railway before you change DNS.
  • Test the www hostname on a prerendered URL. A handle hook does not cover those pages.
Worth noticing
  • The adapter change was not the whole migration. Prerendering failed on Railway after it had worked on his machine.
  • He kept the apex on one service and sent www there from a second Railway app.
Sources and evidence

Verify against the primary material.

Platform behavior changes. Check these sources and the review dates above before executing a production migration.

  1. Vercel: environment variablesAccessed 2026-11-02
  2. Railway: using variablesAccessed 2026-11-02
  3. Railway: working with domainsAccessed 2026-11-02
  4. Railway: public networking specs and limitsAccessed 2026-11-02
  5. Railway: frontend environment variablesAccessed 2026-11-02
  6. Thilo Maier: moving a SvelteKit site from Vercel to RailwayAccessed 2026-11-02