Migrate from Heroku
to vxcloud — in under an hour.
Heroku entered sustaining mode in February 2026. This guide walks you through every step: inventory, provision, database move, deploy, DNS cutover, and shutdown — with the exact commands.
When to migrate, and what to migrate first
The order matters. Migrate stateless apps first, then stateful ones, then long-lived background workers, then the cron-scheduled batch jobs.
The lowest-risk first migration is a stateless web service with no add-ons beyond Postgres. You can complete it in <30 min, prove the playbook end-to-end, then repeat with confidence on the harder apps. Save the apps that hold the most state (queues, large Postgres, paid-add-on tangles) for the third or fourth migration, after your team is comfortable with the workflow.
The seven-step migration
Each step ends with a verifiable signal you can confirm before moving on.
- 1
Inventory the Heroku app
Run `heroku apps:info -a <app>`, `heroku addons -a <app>`, `heroku config -a <app>`, and `heroku domains -a <app>`. Capture: dyno count + size, every add-on (with plan), every config var (mask secrets), every custom domain. Save the four outputs to a file — your migration checklist.
- 2
Sign up for vxcloud and create a workspace
At vxcloud.io/signup. Pick the cloud you want to target (AWS / GCP / Azure / Alibaba / Linode). Connect your cloud credentials — vxcloud stores them in workspace Vault. Connect your Git provider (GitHub / GitLab / Bitbucket).
- 3
Provision a VM that matches your Heroku dyno size
Standard-1X (512 MB, 1× CPU) ≈ AWS t3.small (2 GB, 2 vCPU at burst). Standard-2X (1 GB, 2× CPU) ≈ t3.medium. Performance-M (2.5 GB, dedicated) ≈ c6i.large. Provision with `vxcli vm create --name api --cloud aws --region us-east-1 --instance-type t3.small --key-pair-name AWSPRODKEY2`. The VM comes up in ~90 seconds.
- 4
Migrate Heroku Postgres
Snapshot Heroku's Postgres with `heroku pg:backups:capture -a <app>` then `heroku pg:backups:download -a <app>` for the dump. Provision the new managed Postgres with `vxcli cloud database create-rds my-db --cloud aws --engine postgres --version 16`. Restore with `pg_restore` into the new DB. For zero-downtime, set up logical replication from Heroku PG to the new RDS instance ahead of cutover.
- 5
Deploy your app to the new VM
Pick the matching stack: `vxcli deploy fastapi` / `deploy nodejs` / `deploy django` / `deploy golang` / etc. Pass `--source-dir ./` (or a git URL), `--app-name <heroku-app-name>` for parity, all your env vars from step 1, and `--enable-ssl --domain api.example.com --ssl-email [email protected]` for HTTPS. The deploy runs in ~2-3 minutes.
- 6
Cut DNS over (with low TTL set in advance)
Set your domain's TTL to 60 seconds ~24 hours before cutover. At cutover, update the A record to point at the new VM's public IP. Watch traffic shift in real time with `vxcli services logs <app> --tail`. Heroku traffic drains over 1-5 minutes depending on connection-keep-alive behavior.
- 7
Verify, then scale down Heroku
Confirm: HTTPS endpoint responds, all critical paths return 2xx, error rates look normal, database connections look healthy. After 30 minutes of clean traffic, scale Heroku to zero (`heroku ps:scale web=0 -a <app>`). Keep the Heroku app around for ~7 days as a rollback option, then delete it.
The full command sequence (copy-paste ready)
Walks step 3-6 end-to-end. Replace placeholders with your real values.
# Match the Heroku dyno tier you're migrating from
vxcli vm create \
--name studio-backend-vm \
--cloud aws --region us-east-1 \
--instance-type t3.small \
--key-pair-name AWSPRODKEY2
# Capture the returned public IP for the next steps
export VM_IP=<paste-public-ip-here># 4a) Snapshot Heroku
heroku pg:backups:capture -a my-heroku-app
heroku pg:backups:download -a my-heroku-app # produces latest.dump
# 4b) Provision RDS via vxcloud
vxcli cloud database create-rds studio-db \
--cloud aws --region us-east-1 \
--engine postgres --version 16 \
--instance-type db.t3.micro --storage-size 20 \
--username appuser --password '<set-a-strong-one>'
# 4c) Restore the dump into RDS
pg_restore --verbose --clean --no-acl --no-owner \
-h <rds-endpoint> -U appuser -d studio_db latest.dumpvxcli deploy fastapi \
--source-dir ./ \
--app-name studio-backend \
--entry app.app:app \
--requirements requirements.txt \
--app-port 8000 --http-port 80 \
--env DATABASE_URL=postgres://appuser:...@<rds-endpoint>/studio_db \
--env SECRET_KEY=... \
--env $(vxcli workspace get-credential STRIPE_KEY) \
--enable-ssl --domain api.example.com --ssl-email [email protected] \
--host $VM_IP --ssh-user ubuntu --key-pair-name AWSPRODKEY2# Step 6 — update DNS A record at your registrar to point to $VM_IP
# Confirm propagation with: dig +short api.example.com
# Watch traffic land:
vxcli services logs studio-backend --tail 200 \
--host $VM_IP --ssh-user ubuntu --key-pair-name AWSPRODKEY2
# Step 7 — after 30 min of clean traffic, scale Heroku to zero
heroku ps:scale web=0 -a my-heroku-app
# Keep the Heroku app for ~7 days as a rollback option, then:
# heroku apps:destroy --app my-heroku-app --confirm my-heroku-appHeroku add-on → vxcloud equivalent
Most Heroku add-ons map to one of three patterns: cloud-native resource, SaaS keep-and-use, or container deploy.
| Feature | vxcloud equivalent | Notes |
|---|---|---|
| Heroku Postgres | `cloud.create_rds()` or MetalDB | Both real Postgres; RDS is managed, MetalDB is self-managed (cheaper). |
| Heroku Redis | `cloud.create_redis()` (ElastiCache / MemoryStore) | Or `vxcli deploy container --image redis:7 --ports 6379:6379` for self-managed. |
| Heroku Scheduler | cicd pipeline + cron trigger | Or simple systemd timer on the VM. |
| Papertrail / Logentries | `vxcli services logs --tail` | Or ship to Datadog/Loki via OpenTelemetry collector deployed alongside. |
| New Relic / Scout | Container deploy or SaaS keep-and-use | APM agents work the same way — env-var-configured. |
| Mailgun / SendGrid | Keep as-is, store API key in workspace Vault | SaaS APIs need no change beyond key storage. |
| Cloudinary / Imgix | Keep as-is | Or S3 + Lambda@Edge for self-managed. |
| Memcached | `vxcli deploy container --image memcached:1.6 --ports 11211:11211` | Same VM as the app for low latency. |
| RabbitMQ (CloudAMQP) | Container deploy or managed AmazonMQ | Container is simpler for <1k msg/s. |
| Custom buildpack | Custom Dockerfile (one-time conversion) | Most buildpack steps map cleanly to RUN directives. |
Migration FAQ
Start your Heroku migration in under 60 minutes
Sign up free, follow the seven steps, and have your first app live on vxcloud before lunch.
Related pages
- Best Heroku alternativeWhy pick vxcloud over Render / Railway.
- SSH Deploy AutomationThe deploy workflow under the hood.
- vxcloud vs RenderMost-cited Heroku replacement compared.
- Multi-Cloud ProvisioningProvision the VM first, then deploy.
- Django hostingDjango-specific migration tips.
- FastAPI hostingFastAPI-specific deploy guide.