Moving From Heroku to AWS ECS: A Checklist by Stage
Migrating from Heroku to AWS ECS means replacing buildpacks with containers, dynos with ECS services, add-ons with AWS services, and the release process with your own pipeline. Do it in stages, move the database last, and keep Heroku running until traffic has been stable for a while.
The checklist below is ordered by stage so you can stop and verify between them.
Vendors Covered in this Article
Disclosure: We may earn a commission if you buy through some links on this page. It doesn't change what we recommend.
What do you map before you start?
Heroku bundles many things into one bill. List each and its AWS counterpart:
- Web and worker dynos: become ECS services, with the Procfile process types turning into separate task definitions.
- Release phase: becomes a migration step in your pipeline or a one-off ECS task that runs before the new version takes traffic.
- Scheduler: becomes scheduled tasks, for example EventBridge rules that start ECS tasks.
- Config vars: become environment variables and secrets injected at task start, ideally from a secrets manager.
- Add-ons: Postgres, Redis, email, logging and monitoring each need an AWS or third-party replacement.
- Domains, TLS and review apps: become a load balancer, certificates and whatever preview environment process you build.
Missing items are the main source of surprises, so read your Heroku dashboard and Procfile line by line, and ask whoever set it up what else is hidden there.
How to containerize and stand up the environment
Work through these in order and test after each:
- Write a Dockerfile that reproduces what the buildpack did, and confirm the image runs locally with production-like variables.
- Create a container registry repository and push the image from CI.
- Build the network: a VPC with private subnets for tasks and data, public subnets for the load balancer.
- Define the ECS cluster, task definitions and services, with health checks and resource sizes based on your dyno metrics.
- Set up a load balancer, certificate and a temporary hostname, and test the app end to end there.
- Send logs to a central place and add basic alarms before you move traffic.
Choosing between launch types affects cost and operations; see ECS Fargate vs EC2 cost. If you're weighing ECS against Kubernetes first, read AWS ECS vs Kubernetes for tech startups.
How do you move the database with little downtime?
The database is the riskiest step, so rehearse it. For small databases, a dump and restore during a short maintenance window is the simplest, with the application in read-only or offline mode while you copy. For larger ones, look for a replication-based approach that keeps the AWS copy in sync until cutover; what's possible depends on your Heroku plan and options, so check current documentation.
Rehearse at least once with a copy. Time it, verify row counts and run the app's tests against the restored database. Plan the cutover: stop writes, take the final copy, switch connection strings, verify, then reopen. Keep the old database untouched and read-only for a while as your fallback. For the target database options, see how a Postgres move is structured in the Supabase to RDS migration guide, which applies to any managed Postgres target.
What does cutover day look like?
Lower your DNS record's time-to-live a day or two before, so a change or rollback propagates quickly. On the day:
- Freeze deploys on Heroku.
- Complete the database move if it hasn't happened.
- Point DNS to the AWS load balancer, and watch error rates, latency and queue depth.
- Confirm scheduled jobs and workers run on AWS only, so tasks don't run twice or not at all.
- Check outbound integrations that whitelist your IP addresses, since AWS addresses differ from Heroku's.
- Keep the Heroku app scaled down but intact for your rollback window.
Have a named person own rollback, with the trigger conditions written down: for instance, error rate above a threshold for ten minutes.
What should you check afterward?
Migrations often quietly change delivery speed. DORA's 2024 report describes lead time for changes from under a day to one to six months across performance clusters1, so measure yours before and after. If deploys got slower, fix the pipeline before declaring victory.
Then tidy up: remove unused add-ons, cancel the Heroku plan only after your rollback window closes, document the new runbook, and set cost alerts. Note what Heroku gave you for free, such as router logs and automatic restarts, and confirm you've replaced each.
What Good Looks Like
Every dyno, add-on, scheduled job and config var has a named AWS replacement, and you've rehearsed the database move and the rollback.
Building The Capability (5-Stage Skill Ladder)
How to Get Started
Disclosure: We may earn a commission if you buy through some links on this page. It doesn't change what we recommend.
Frequently Asked Questions
How long does a Heroku to AWS ECS migration take?
It depends on how many services, add-ons and data you have. A small app can move in a few weeks including rehearsals, while complex ones take longer. Plan for testing and a rollback period, not just build time.
What replaces the Heroku Procfile on ECS?
Each process type becomes its own ECS task definition and service, with the command set in the container. Scheduled tasks become rules that start one-off ECS tasks on a timer.
Can I migrate the database without downtime?
Sometimes. Replication-based approaches can keep two copies in sync until cutover, but options depend on your setup. For many small databases, a short maintenance window with dump and restore is simpler and safer.
Should I keep Heroku running after cutover?
Yes, scaled down, for a rollback window. Keep the old database read-only and only cancel once you've had stable traffic and confirmed jobs, integrations and backups work on AWS.
Sources
Where we quote a benchmark, we show its source. Other figures in this guide are estimates or general guidance, so check them against your own numbers.
- Lead time for changes by DORA performance cluster (upper bound, days). DORA Accelerate State of DevOps 2024 (Google Cloud), cluster table via Octopus Deploy analysis, 2024.
Related Guides
ECS on Fargate or EC2: How to Compare the Real Cost
Compare the cost of ECS on Fargate and on EC2 using utilization, bin-packing, operations time and discounts, with a worked example and a decision rule.
AWS ECS vs Kubernetes for Tech Startups: Container Orchestration Compared
Compare AWS ECS and Kubernetes for tech startups: DevOps headcount spend, Fargate serverless containers, operational complexity, and deployment speed.
Migrating From Supabase to Amazon RDS: A Planning Guide
Plan a move from Supabase to Amazon RDS: what Supabase gives you beyond Postgres, extension and role checks, dump and restore, low-downtime cutover.
Kubernetes vs. ECS When You Deploy Into a Client's Account
A custom software shop's infrastructure choice has to survive the handoff at the end of the contract. Here's a worked example for picking Kubernetes or ECS.
Kubernetes vs AWS ECS vs HashiCorp Nomad: Container Platforms Compared
Compare Kubernetes, AWS ECS, and HashiCorp Nomad for container orchestration, DevOps overhead, cluster autoscaling, deployment velocity, and hosting COGS.
Moving a Next.js App From Vercel to AWS: Options and Steps
Decide whether and how to move a Next.js app from Vercel to AWS: container versus serverless options, caching, images, previews, DNS cutover and rollback.