Guide

Migrate from Heroku to Railway: Step-by-Step

Migrating from Heroku to Railway means connecting your git repo, letting Railway auto-detect your buildpack, adding your environment variables and database, and pointing your domain at Railway once it's live. Railway's pricing is usage credit, not a flat fee, so plan around actual container consumption.

What you need first

Before migrating, you need your app's source in a git repository Railway can connect to, a list of the environment variables and add-ons (databases, Redis, etc.) your Heroku app currently depends on, and an understanding of Railway's usage-credit pricing model since it works differently from Heroku's per-dyno fee. Railway's subscription isn't a feature tier — it's a monthly credit that gets consumed by your containers' actual CPU and memory usage, so the plan you pick determines both your per-service resource ceiling and how much usage is covered before extra charges kick in.

If you're not sure Railway is the right target yet, our Railway vs Render comparison and Heroku alternatives roundup cover how it stacks up against other Heroku successors before you commit to the migration.

It also helps to have a rollback plan before you start. Since Heroku and Railway can run in parallel during the migration, don't tear down your existing Heroku app until traffic has been fully cut over and stable for a while. Keep your Heroku add-ons and database active in a read-only or paused state rather than deleting them immediately, in case you need to pull data or diff a configuration value during troubleshooting.

Step-by-step

Start by exporting your Heroku app's configuration: run heroku config to list every environment variable, and note which add-ons (Postgres, Redis, background workers) your app uses, since those need to be recreated on Railway rather than migrated automatically. Then connect your git repository to Railway — it auto-detects most common buildpacks and frameworks, so for a standard app you typically don't need to write any container or infrastructure configuration by hand.

Next, recreate your environment variables inside the Railway project settings, matching what you exported from Heroku. If your app uses a database, provision the equivalent Railway service (Postgres, Redis, etc.) and update your connection string accordingly, then run your migration or restore process to bring your data over. Deploy the app and verify it starts cleanly and passes whatever health checks your framework expects.

Once the app is running on Railway and you've confirmed it behaves correctly under real traffic, update your DNS to point your domain at Railway instead of Heroku. Keep the Heroku app running in parallel during this step so you can roll back quickly if something's wrong, then decommission the Heroku app once you're confident the cutover succeeded.

Background workers and scheduled jobs deserve their own step, since they're easy to forget when you're focused on the main web process. Recreate each worker as its own Railway service pointed at the same repo, and re-add any scheduled task or cron configuration your Heroku app relied on, since Railway doesn't infer these automatically from your Heroku setup — you have to define them explicitly on the new platform.

Common problems

The most common problem is underestimating what a service will actually cost once traffic is real, since Railway bills by consumption rather than a flat plan fee. Hobby at $5/mo includes $5/month of credit, which covers a genuinely low-traffic app, but anything with real traffic will consume credit beyond that and get billed for the difference — budget for this rather than assuming the plan price is your ceiling.

Another common issue is hitting the free plan's limits during testing: the free tier's $1/month of credit and 0.5 GB per-service cap is quite small, so if your migration testing is running into resource limits, that's likely why — move to Hobby (48 vCPU / 48 GB per-service ceiling) or Pro (1,000 vCPU / 1 TB per-service ceiling) for anything beyond a quick smoke test. Missing environment variables are also a frequent source of post-migration bugs, since Railway doesn't automatically import them from Heroku — double-check every variable your app reads against what you've configured before assuming a deploy failure is a Railway problem rather than a missing config value.

What to do next

Once your migration is stable, monitor your Railway usage against your plan's included credit for a few billing cycles to understand your actual cost pattern before committing to a long-term budget. If your app is consistently running above the Hobby plan's $5/month included credit, moving to Pro at $20/mo with $20/month of credit included may work out cheaper than paying Hobby's overage rates, depending on your usage.

If you're weighing Railway against other infrastructure options for a broader project, our DigitalOcean vs Vultr and DigitalOcean vs Hetzner comparisons cover more traditional VPS pricing models, which is a useful contrast if usage-based billing on Railway ends up costing more than a fixed-price server would for your specific traffic pattern.

It's also worth setting up basic monitoring and alerting on Railway from day one, rather than after your first surprise bill. Because cost tracks resource consumption directly, a memory leak or a runaway background job shows up as a cost spike as much as a performance problem, so treat usage alerts as part of your operational setup, not an afterthought. Pair that with a periodic review of which services are actually still needed — it's easy to leave a staging environment or an old preview deploy running long after it stopped being useful, and on a usage-billed platform, unused services still draw down your credit every month.

Finally, document the migration itself while it's fresh: the environment variables you moved, the add-ons you recreated, and any Railway-specific configuration you added. If you ever need to repeat this process for a second app, or explain to a teammate why a particular service is configured the way it is, having that written down saves you from re-deriving it from scratch the next time around.

Frequently asked questions

How much does Railway cost compared to Heroku?

Railway's subscription is usage credit rather than a flat fee: Hobby is $5/mo and includes $5/month of credit, so a low-traffic app effectively costs just the subscription with usage covered. Pro is $20/mo with $20/month of credit included, and usage above the included credit is billed on top.

Can I try Railway for free before migrating?

Yes. Railway's free trial gives a one-time $5 credit valid for 30 days with services capped at 2 vCPU and 1 GB. There's also an ongoing free plan with $1/month of credit and a 1 vCPU / 0.5 GB cap per service, though that's too small for most real apps.

Does Railway deploy directly from a git repo like Heroku?

Yes, Railway deploys from a connected git repository with no container or infrastructure configuration required, similar to Heroku's git-push workflow. You connect the repo, Railway builds it, and subsequent pushes trigger new deploys automatically.

What's the biggest gotcha when migrating from Heroku to Railway?

The biggest gotcha is that Railway's cost scales with actual resource consumption rather than being capped by a flat plan fee, so usage above your included credit gets billed on top. Forecasting your bill means estimating container CPU and memory usage, not just request volume, which is a different mental model than Heroku's dyno-based pricing.