Heroku → Railway
Move a Heroku application to Railway with explicit handling for process types, databases, add-ons, variables, storage, jobs, domains, observability, deployment behavior, and rollback.
Should you make this move?
Both platforms have a case. Compare what you gain with what you give up before scheduling the cutover.
Heroku
- Git-based deploys, buildpacks, and add-ons offer an exceptionally approachable platform
- Managed deployments reduce infrastructure and release-management work
- Pricing and infrastructure control become limiting as applications grow
- Runtime assumptions, platform services, and pricing models shape the architecture
Railway
- Fast service and database provisioning gives developers a low-friction application platform
- Managed deployments reduce infrastructure and release-management work
- Usage pricing and infrastructure abstraction can become limiting at scale
- Runtime assumptions, platform services, and pricing models shape the architecture
Railway: Fast service and database provisioning gives developers a low-friction application platform. This removes a major source-side concern: Pricing and infrastructure control become limiting as applications grow.
What you lose: Git-based deploys, buildpacks, and add-ons offer an exceptionally approachable platform. What you inherit: Usage pricing and infrastructure abstraction can become limiting at scale.
Know the shape of the move.
This timeline assumes
- One app with web, worker, scheduled jobs, Postgres, and common add-ons.
- The simple Railway guide supports one Procfile process; multi-process apps are modeled as services.
- Ephemeral filesystem assumptions are removed.
- Production data receives a tested backup and restore.
- Heroku stays intact through a stable rollback window.
What survives the move.
“Partial” and “manual” are not footnotes. They are work that must be scheduled and verified.
| Item | Outcome | Impact | What happens | Mitigation |
|---|---|---|---|---|
| Application source | clean | critical | Railway deploys the same repository or local source. | Build the exact production commit. |
| Procfile web process | partial | high | Railway supports Procfiles, but its simple guide notes one process. | Create separate services for web, worker, and other processes. |
| Config vars | partial | critical | Railway can import Heroku variables, but scope and generated values require review. | Classify, rotate secrets, and validate service references. |
| Heroku Postgres | manual | critical | Database migration is separate from the simple app guide. | Dump/restore or replicate with measured write freeze and reconciliation. |
| Add-ons | lost | critical | Marketplace resources and credentials do not transfer automatically. | Choose and test one replacement per add-on. |
| Scheduled jobs | manual | high | Heroku Scheduler configuration is not application source. | Recreate timing, timezone, concurrency, and alerts. |
| Domains and TLS | manual | critical | Custom domains and certificates require destination setup and DNS cutover. | Pre-provision hostname, TLS, and rollback records. |
| Buildpacks and stack behavior | partial | critical | Detection, OS packages, release commands, and runtime versions can differ. | Pin runtime and dependencies and test release phase behavior. |
| Logs, metrics, and alerts | lost | high | Historical operational data remains in Heroku/add-ons. | Export required evidence and rebuild monitors. |
| Filesystem data | lost | critical | Runtime local files are not a portable durable store. | Move required files to object storage and verify references. |
Where each thing goes.
| Source | Destination | Method | Notes |
|---|---|---|---|
| Heroku app | Railway project | manual | Group related services. |
| web dyno | Web service | transform | Set start command and health check. |
| worker dyno | Worker service | manual | Separate from web. |
| Config var | Service/project variable | transform | Review scope and rotate. |
| Heroku Postgres | Railway Postgres or external database | manual | Use dump/restore or replication. |
| Add-on | Railway service or external provider | manual | No universal mapping. |
| Scheduler job | Cron job | manual | Preserve timezone and concurrency. |
| Custom domain | Railway domain | manual | Switch DNS after TLS passes. |
Make the move recoverable.
Create the source-of-truth backup
Preserve code, data, configuration, add-on state, and recovery evidence.
- Inventory dynos, processes, releases, buildpacks, vars, databases, add-ons, domains, drains, jobs, storage, and integrations.
- Tag the production commit and export configuration names.
- Create and restore-test database and file backups.
- Export required logs, metrics, and add-on data.
- Record DNS and rollback values.
Proof to capture: A manifest covers every process, secret consumer, data store, job, domain, and integration with restore evidence.
Service topology
Split Heroku process types into explicit Railway services.
- Map web, worker, release, and cron behavior.
- Set dependencies and health checks.
- Test scaling and restart.
Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.
Data and add-on replacement
Move durable state without hidden dependencies.
- Choose replacements.
- Rehearse data copy.
- Reconcile counts and application scenarios.
Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.
The things most likely to hurt.
These are operating limits. Treat every “Stop if” condition as a blocked migration, not a suggestion.
Only the web process moves
Workers or release tasks are absent.
- Consequence
- Queues stop and deploys leave schema inconsistent.
- Mitigation
- Model every process explicitly.
Stop if: Any production process has no destination.
Database writes diverge
Both databases accept writes.
- Consequence
- Orders or records split.
- Mitigation
- Use one write authority and reconcile final delta.
Stop if: A write lands outside the declared primary.
Imported variables expose or mis-scope secrets
A service can read unrelated secrets.
- Consequence
- Credential exposure.
- Mitigation
- Rotate and scope variables per service.
Stop if: Any untrusted service reads production secrets.
Do the work in this order.
- Days 1–3 · inventory
Inventory
10–16 hours active3 days elapsedOwner review waiting- Inventory topology and state.
- Choose replacements and rollback.
Depends on: Heroku and Railway admins
Stop / go checkpointBuild?
Go when: Every process and store is mapped.
Stop when: Critical state or add-on is unknown.
- Days 4–5 · backup
Backup and restore
6–10 hours active2 days elapsedBackup transfer waiting- Create backups.
- Run restore drill.
Depends on: Inventory
Stop / go checkpointPilot?
Go when: Data restores and manifests reconcile.
Stop when: Recovery fails.
- Days 6–10 · pilot
Build destination
12–22 hours active5 days elapsedBuilds and DNS waiting- Deploy services and variables.
- Restore data and add-ons.
- Test jobs and health.
Depends on: Backup
Stop / go checkpointRehearse?
Go when: All scenarios and monitors pass.
Stop when: Any process or state is wrong.
- Days 11–14 · rehearse
Cutover rehearsal
4–9 hours active4 days elapsedData copy timing waiting- Measure final data copy.
- Practice DNS and rollback.
- Load-test critical paths.
Depends on: Pilot
Stop / go checkpointCut over?
Go when: Window and rollback meet target.
Stop when: Data loss or downtime exceeds approval.
- Days 15–20 · cutover
Freeze and observe
3–13 hours active3–6 days elapsedDNS and production signals waiting- Freeze writes.
- Copy final data.
- Switch DNS and jobs.
- Observe.
Depends on: Rehearsal
Stop / go checkpointClose rollback?
Go when: Data, traffic, jobs, and alerts pass.
Stop when: Critical errors or divergence appears.
Cut over with a way back.
Cutover
Move production traffic and writes to Railway with one authoritative datastore.
- Freeze deploys and writes.
- Create final backups and copy data.
- Deploy the approved commit.
- Switch domains, jobs, workers, and integrations.
- Run smoke and reconciliation checks.
- Keep Heroku scaled and recoverable.
Proof to capture: Railway serves production, data reconciles, workers/jobs run once, and monitors pass.
Rollback
Return traffic and writes to Heroku.
- Stop Railway writes and jobs.
- Capture destination deltas.
- Restore or apply approved data to Heroku.
- Restore DNS, workers, scheduler, and integrations.
- Run smoke checks.
Proof to capture: Heroku again owns traffic and data with current approved records.
- Data mismatch
- Critical process absent
- Error or latency threshold exceeded
- Job duplication
- Secret/access failure
Prove the migration worked.
Every blocking check must pass. Capture the evidence before cleanup begins.
| Pass | ID | Check | Method | Expected result | Evidence |
|---|---|---|---|---|---|
V-01Blocking | Production commit | Compare release SHA and dependencies. | Exact approved source. | Release record. | |
V-02Blocking | Web, worker, release, cron | Exercise each process. | One healthy instance path. | Process log. | |
V-03Blocking | Database reconciliation | Compare counts, checksums, and scenarios. | No unexplained variance. | Data report. | |
V-04Blocking | Replacement behavior | Trigger each dependency. | Approved result. | Dependency log. | |
V-05Blocking | Variables and secrets | Audit scope and runtime access. | Least privilege and correct values. | Config audit. | |
V-06Blocking | DNS and TLS | Resolve and inspect certificates. | Correct target and valid TLS. | DNS/TLS output. | |
V-07Blocking | Logs and alerts | Generate known events. | Logs arrive and alerts fire once. | Alert log. | |
V-08Blocking | Rollback | Run rehearsal or isolated restore. | Recovery meets target. | Recovery report. |
Remove the scaffolding safely.
Safe after: Seven stable days and one successful deploy plus scheduled-job cycle.
- Archive backups and evidence.
- Revoke Heroku tokens and drains.
- Remove obsolete add-ons only after retention review.
- Keep Heroku intact through rollback window.
- Update operations documentation.
- Schedule restore and secret reviews.
Built to be reviewed.
Tested 2026-07-19. Next scheduled review: 2026-10-19.
- Railway: migrate from HerokuAccessed 2026-07-19
- Heroku: export Postgres dataAccessed 2026-07-19
- Railway: databasesAccessed 2026-07-19