| Heroku | Railway | |
|---|---|---|
| Free Tier | None (removed 2022) | $5/month credit |
| Deploy | Git push or GitHub | GitHub (auto-deploy) |
| Databases | Addons (Heroku Postgres) | Built-in (1-click) |
| Docker | Container registry | Native support |
| UI | Dated dashboard | Modern, real-time |
Start by making a complete inventory of everything running on Heroku. Use the Heroku CLI to list everything:
# List all apps
heroku apps
# For each app, get details
heroku config -a your-app-name # Environment variables
heroku addons -a your-app-name # Addons (databases, etc.)
heroku ps -a your-app-name # Dyno/process info
Document each app's addons (Postgres, Redis, Papertrail, etc.), environment variables, and the buildpack it uses. This is your migration checklist.
Head to railway.app and sign up with your GitHub account. This gives Railway access to your repositories for auto-deployment.
Click "New Project" and select "Deploy from GitHub repo". Choose the repository that contains your Heroku app's code. Railway will auto-detect your language and framework.
Railway uses Nixpacks instead of Heroku's buildpacks. Nixpacks automatically detects your language (Node.js, Python, Ruby, Go, etc.) and builds accordingly. In most cases, it just works without any configuration.
This is the most important step. Copy every environment variable from Heroku to Railway.
Export all config vars from Heroku:
heroku config -a your-app-name --json
In your Railway project, go to the Variables tab. You can add them one by one or use the "RAW Editor" to paste multiple variables at once in KEY=value format.
Don't copy the DATABASE_URL yet - you'll get a new one from Railway's database in the next step. Same for any addon-specific URLs (Redis, etc.).
If you're using Heroku Postgres (or Redis, MySQL), create the equivalent on Railway. In your project, click "New" → "Database" and select Postgres (or whichever you need).
Railway will provision the database instantly and provide a connection URL. It automatically creates a DATABASE_URL variable in your service.
To migrate your data, export from Heroku and import to Railway:
# Export from Heroku
heroku pg:backups:capture -a your-app-name
heroku pg:backups:download -a your-app-name
# Or use pg_dump directly
pg_dump -Fc --no-acl --no-owner \
$(heroku config:get DATABASE_URL -a your-app-name) \
> heroku_backup.dump
# Import to Railway (use the Railway DATABASE_URL)
pg_restore --no-acl --no-owner \
-d "your-railway-database-url" \
heroku_backup.dump
Once your variables are set and database is ready, Railway will auto-deploy from your GitHub repo. If it hasn't already deployed, push a small commit to trigger it:
git commit --allow-empty -m "trigger railway deploy"
git push
Watch the build logs in Railway's dashboard. If the build fails, check:
Start command: Railway looks for a Procfile, start script in package.json, or auto-detects. If it's wrong, set a custom start command in Railway's service settings.
Port: Railway sets the PORT environment variable automatically. Make sure your app reads from process.env.PORT (not a hardcoded port).
Build command: Railway auto-detects, but you can override in settings if needed.
Railway gives you a free .up.railway.app subdomain. Test your app on this URL first to make sure everything works.
Once verified, add your custom domain in Railway under Settings → Custom Domain. Railway will give you a CNAME value to add to your DNS:
Type: CNAME
Name: your-subdomain (or @ for root)
Value: your-app.up.railway.app
Don't forget to update any external services that reference your Heroku app URL - webhooks, OAuth callback URLs, API integrations, etc. Change them to your new Railway domain.
Railway's dashboard shows real-time CPU, memory, and network usage for each service. Keep an eye on it during the first few days to understand your resource consumption.
The $5/month free credit covers roughly:
Small web app: 512MB RAM running 24/7 - easily covered.
Web app + database: Usually covered, but may use the full $5.
Multiple services: You may exceed $5/month - upgrade to the Pro plan ($20/month with usage credits).
Set up usage alerts in Railway's settings to avoid surprises. If you're coming from Heroku's paid plan, Railway will almost certainly be cheaper.
Heroku buildpacks don't exist on Railway. Instead, Railway uses Nixpacks which auto-detects your language and build process. In 90% of cases it works out of the box. If not, add a railway.toml or Dockerfile for custom builds.
If you use Heroku Scheduler for cron jobs, switch to Railway's built-in cron functionality. You can create a separate service in your Railway project with a cron schedule in your railway.toml file.
Railway's $5 free credit resets monthly, but it can run out if you're not careful. A database running 24/7 uses more resources than you might expect. Monitor your usage dashboard during the first month to set expectations.
I'll handle the Heroku to Railway switch for you. Apps, databases, environment variables - zero downtime migration.
Work with me →