Skip to main content
Moving from Heroku changes both the deployment platform and the infrastructure owner. Before migrating workloads, prepare the Ubuntu servers, DNS, backup storage, monitoring, and provider credentials that Heroku previously operated for you.

Compare the tradeoffs

Towbar

✅ Pros

  • You choose the servers, regions, network paths, storage providers, and cost profile instead of renting an opaque dyno abstraction.
  • Deployment policy is reviewed in Git, while the Towbar instance keeps runtime credentials and application secret values under your control.
  • Towbar combines deployment history, host capacity, Scout monitoring, vulnerability results, backups, and restores for its supported workloads.

⚠️ Cons

  • You become responsible for host security, capacity, operating-system updates, backups, disaster recovery, networking, and the Towbar control plane.
  • Towbar has no equivalent to Heroku’s add-on marketplace, managed dyno fleet, Private Spaces, or platform autoscaling.
  • Moving a mature Heroku app often means replacing add-ons and splitting Procfile process types into several Towbar Apps.

Heroku

✅ Pros

  • Heroku’s dyno and release model handles builds, process supervision, routing, logs, scaling, and release history without exposing servers.
  • Pipelines, review apps, add-ons, one-off dynos, and managed data services form a mature workflow with a large ecosystem.
  • Teams can scale processes and replace infrastructure without maintaining the underlying hosts.

⚠️ Cons

  • You have limited control over the host, network, and runtime internals, and platform behavior can become part of the application contract.
  • Dyno filesystems are ephemeral, and durable state must live in an add-on or external service.
  • Costs rise with dyno count and managed services, while moving away requires replacing add-ons, config, routing, and operational assumptions.

1. Inventory each app

Record the repository and deployed branch, buildpacks or container image, Procfile process types, release phase, config vars, add-ons, domains, TLS, scheduler jobs, drains, database plans and versions, and any filesystem writes. Heroku config vars become environment variables at runtime; preserve their names and scope without committing their values. Map the app before provisioning replacements:

2. Make the build reproducible

Choose a supported Towbar builder or add a Dockerfile that reproduces the Heroku build and start behavior. Pin runtime versions and external images. Heroku may inject platform-specific variables or infer a process; declare every required input in the Towbar workload instead. Create separate workload files when long-running process types need different commands, limits, health checks, or deployment controls. Deploy them to a temporary hostname and verify web requests, workers, jobs, queues, email, OAuth, webhooks, uploads, and outbound provider access.

3. Move add-ons and data

Replace each add-on with a Towbar Resource or an external service and update the corresponding secret. Do not assume an add-on’s connection URL, TLS behavior, or extensions match the replacement. Heroku Postgres backups use PostgreSQL’s logical dump format. Follow Heroku’s export instructions, match the destination major version and extensions, restore to a disposable target, and test application migrations before the production window. Move uploaded files from their object store or attached service; Heroku dyno filesystems are ephemeral.

4. Cut over deliberately

Lower DNS TTL, enable Heroku maintenance mode or otherwise stop writes, create the final data export, restore it, and start Towbar workers only after verification. Move the production domain, then confirm TLS, health, logs, jobs, notifications, backups, and representative reads and writes. Retain the stopped Heroku app and document the data boundary for rollback. Continue with Install Towbar, Apps, and PostgreSQL.
Last modified on September 22, 2026