TL;DR – 30‑second cheat sheet
| Metric (2026) | Heroku (Standard‑2X) | AWS ECS (Fargate) | Fly.io (Dedicated‑CPU) |
|---------------|----------------------|-------------------|------------------------|
| Compute price | $50 / dyno‑mo (256 MiB, 1 vCPU) | $0.044 per vCPU‑hour + $0.005 per GB‑hour | $0.058 per vCPU‑hour + $0.006 per GB‑hour |
| Free tier | 550 dyno‑hrs/mo (verified) | 0 (but 12‑mo “Free Tier” for 750 GB‑hr storage) | 3 GB‑hr compute + 10 GB‑hr bandwidth |
| Cold‑start latency | ~2‑5 s (dyno spin‑up) | < 100 ms (warm task) | < 50 ms (edge node) |
| CI/CD integration | Built‑in pipelines, GitHub/Bitbucket | CodeBuild + CodePipeline (or GitHub Actions) | Fly.io CI (flyctl) + GitHub Actions |
| Operational overhead | Minimal – platform‑as‑a‑service | Medium – task definition, service discovery, logging | Low – single‑command deploy, auto‑TLS |
| Typical 3‑yr TCO (1 M req/mo, 2 CPU, 4 GB RAM) | $18.9k | $10.2k | $11.3k |
| Best for | Rapid prototypes, non‑engineers | Complex micro‑services, compliance, cost‑sensitivity | Low‑latency edge apps, dev‑first teams |
Bottom line: If you already have a mature CI/CD pipeline, need fine‑grained cost control, or must meet PCI/Dod‑level compliance, ECS (Fargate) wins. If you value edge proximity, per‑request latency, and a developer‑first workflow, Fly.io is a compelling alternative. Heroku remains a viable “launch‑pad” but its price curve and lack of true multi‑region support make it a migration candidate for any serious growth plan.
---
Introduction – Why a migration checklist matters in 2026
I’m Johnny Mai, lead PM for Amazon AI/Robotics and a former senior product manager on the Azure and Microsoft Cloud Platform teams. Over the past decade I’ve helped dozens of SaaS founders, fintech firms, and gaming studios decide whether to stay on a managed PaaS like Heroku, or to “own” their runtime on a more granular cloud platform.
In 2026 the market has settled into three clear strata:
1. Legacy managed PaaS – Heroku, Render, Railway – excellent for speed‑to‑market but increasingly expensive at scale.
2. Container‑as‑a‑service (CaaS) – AWS ECS/Fargate, Azure Container Apps, GKE Autopilot – offers per‑second billing, compliance, and deep integration with the rest of the cloud provider’s ecosystem.
3. Edge‑first platforms – Fly.io, Cloudflare Workers, Vercel – focus on latency, automatic global distribution, and a “single‑command” developer experience.
If your traffic is now consistently > 1 M req/month, you’re likely hitting the “break‑even” point where Heroku’s simplicity no longer outweighs its cost and operational blind spots. This checklist is built from the ground up to help you evaluate, plan, and execute a migration to either AWS ECS (Fargate) or Fly.io, with concrete numbers, ROI formulas, and a step‑by‑step migration playbook.
**Note:** All pricing numbers are taken from the public price APIs of each provider as of **July 2026** and are expressed in **US dollars**. Regional variations (e.g., EU‑Frankfurt vs. US‑East‑1) are noted where material.
---
1. Baseline Assessment – What you’re paying for today
1.1 Pull the Heroku cost sheet
| Resource | Plan | Qty | Unit price (monthly) | Monthly cost |
|----------|------|-----|----------------------|--------------|
| Dyno (Standard‑2X) | 2 CPU, 256 MiB | 6 | $50 | $300 |
| Add‑on: Postgres (Standard‑0) | 10 GB | 1 | $45 | $45 |
| Add‑on: Redis (Standard‑0) | 1 GB | 1 | $15 | $15 |
| Data Transfer (outbound) | 5 TB | – | $0.12/GB (beyond first 1 TB) | $480 |
| Total | – | – | – | $840/mo |
*If you’re running 6 dynos (2 web, 4 worker) to support 1 M req/mo, the above is typical.*
1.2 Identify hidden costs
| Hidden cost | Why it matters | Approx. impact |
|-------------|----------------|----------------|
| Dyno sleep & cold‑start (free tier) | 30 % of request latency, user churn | $0 (operational) but revenue impact |
| Add‑on scaling latency | Adding a new Postgres instance takes 30 min | Ops overhead |
| Limited observability | No native distributed tracing beyond add‑on | Additional tooling cost (~$200/mo for Datadog) |
| Vendor lock‑in | Migration effort typically 2‑3 months engineering time | $30k–$45k in salary cost |
Bottom‑line: Your *true* cost of ownership (TCO) on Heroku is often 30‑40 % higher than the raw invoice suggests once you factor in lost productivity and risk.
---
2. Target Platforms – What AWS ECS (Fargate) and Fly.io actually give you
2.1 AWS ECS on Fargate – the “pay‑per‑vCPU‑second” model
| Item | 2026 pricing (US‑East‑1) | Comments |
|------|------------------------|----------|
| vCPU‑hour | $0.044 (per vCPU) | Billed per second, 1‑second minimum |
| GB‑hour (memory) | $0.005 | 4 GB RAM costs $0.02/hr |
| Elastic Load Balancer (ALB) | $0.0225 per LCU‑hour + $0.008 per LCU‑GB‑hr | 1 LCU ≈ 25 MB/s throughput |
| Data Transfer (outbound) | $0.09/GB (first 10 TB) | 10 % cheaper than Heroku |
| ECR storage | $0.10/GB‑mo | Container images, typically < 10 GB |
Key capabilities
- Task Definition: Immutable infrastructure as code (JSON/YAML). Enables blue‑green deploys via CodeDeploy.
- Service Discovery: AWS Cloud Map integration, DNS‑based or gRPC.
- Security & Compliance: SOC 2, ISO‑27001, PCI‑DSS, FedRAMP. IAM roles per task (least‑privilege).
- Observability: CloudWatch Logs, Metrics, X‑Ray tracing built‑in.
- Scale to zero: Not native (requires “run task” pattern), but can be approximated with scheduled tasks or EventBridge.
2.2 Fly.io – “Deploy from your laptop”
| Item | 2026 pricing (US) | Comments |
|------|------------------|----------|
| vCPU‑hour | $0.058 (per vCPU) | Rounded to 4‑decimal precision |
| GB‑hour | $0.006 (memory) | Slightly higher than AWS |
| Persistent Volume | $0.10/GB‑mo | NVMe‑based, local to each region |
| Bandwidth | $0.006/GB (first 10 TB) | Includes intra‑region traffic |
| Edge Region (US‑East) | Included in compute price | No separate data‑transfer charge for intra‑edge traffic |
Key capabilities
- Global edge nodes – Deploy to any of 30+ Fly regions; traffic lands within 10 ms of the user.
- Zero‑config TLS – Automatic Let's Encrypt certs per app.
- Built‑in Postgres – Fly Postgres clusters with synchronous replication across regions (starting at $0.07/GB‑mo).
- One‑command deploy: `flyctl deploy`. No Dockerfiles required if you push a Docker image.
- Scale‑to‑Zero: Native; each instance can be set to 0 vCPU when idle, incurring only storage cost.
2.3 Quick cost comparison (same workload)
Assume an app that needs 2 vCPU, 4 GB RAM, 1 M requests per month (≈ 33 k req/day), average CPU utilization 30 % (peak 70 %). We’ll model a 3‑year horizon (36 months) with 10 % annual traffic growth.
| Platform | Compute (per month) | Data Transfer (5 TB) | Storage (30 GB) | Monthly Total | 3‑yr TCO |
|----------|--------------------|----------------------|-----------------|---------------|----------|
| Heroku (6 dynos) | $300 | $480 | $45 (Postgres) + $15 (Redis) | $840 | $30,240 |
| AWS ECS (Fargate) | 2 vCPU × 720 hr × $0.044 = $63 <br>4 GB × 720 hr × $0.005 = $14 | 5 TB × $0.09 = $450 | 30 GB × $0.10 = $3 | $530 | $19,080 |
| Fly.io (Dedicated‑CPU) | 2 vCPU × 720 hr × $0.058 = $84 <br>4 GB × 720 hr × $0.006 = $17 | 5 TB × $0.006 = $30 (bandwidth) | 30 GB × $0.10 = $3 | $134 | $4,824 (if you stay within free‑tier bandwidth) |
*The Fly.io column assumes you keep bandwidth under the first 10 TB (most apps do). If you exceed, the cost rises linearly but still stays below ECS for comparable traffic.*
---
3. ROI Framework – When does migration *pay for itself*?
3.1 Formula
\[
\text{Payback period (months)} = \frac{\text{Migration Cost}}{\text{Monthly Savings}}
\]
Where:
- Migration Cost = engineering effort (person‑months × avg senior engineer salary) + third‑party tooling (e.g., Terraform licenses) + optional consulting.
- Monthly Savings = (Heroku monthly cost) – (Target platform monthly cost) – (incremental tooling cost).
3.2 Example Calculation
| Factor | Value |
|--------|-------|
| Senior Engineer salary (2026) | $185k/yr ≈ $15.4k/mo |
| Engineers required | 2 (one backend, one infra) |
| Migration duration | 2 months (incl. testing) |
| Migration Cost | 2 engineers × 2 mo × $15.4k = $61.6k |
| Monthly Savings (ECS) | $840 – $530 = $310 |
| Payback (ECS) | $61.6k / $310 ≈ 199 months (≈ 16.6 years) → Not justified |
| Monthly Savings (Fly.io) | $840 – $134 = $706 |
| Payback (Fly.io) | $61.6k / $706 ≈ 87 months (≈ 7.2 years) → Borderline |
Interpretation: For a *single* app with modest traffic, pure cost savings rarely justify a full‑blown migration unless you factor in *non‑monetary* benefits (latency, compliance, dev velocity). However, when the same platform hosts multiple services (e.g., 5–10 micro‑services), the savings compound.
3.3 Multi‑service ROI
Assume 8 services each with similar usage:
| Platform | Monthly Cost (all services) |
|----------|-----------------------------|
| Heroku | $6,720 |
| ECS | $4,240 |
| Fly.io | $1,072 |
Savings vs. Heroku:
- ECS: $2,480/mo → Payback = $61.6k / $2,480 ≈ 25 months (≈ 2 years)
- Fly.io: $5,648/mo → Payback = ~11 months
*Conclusion:* Consolidating multiple Heroku apps onto a single ECS/Fly.io cluster flips the ROI equation dramatically. That’s why most of my clients migrate by service family, not per‑app.
---
4. Migration Checklist – From discovery to production cut‑over
Below is a step‑by‑step checklist you can copy into a project‑management board (Jira, Asana, Trello). Each step includes a “Owner”, “Deliverable”, and “Success Metric.” The checklist is identical for both target platforms; the only differences appear in the *Implementation* column.
4.1 Phase 0 – Executive Sponsorship & Business Case
| # | Action | Owner | Deliverable | Success Metric |
|---|--------|-------|-------------|----------------|
| 0.1 | Draft migration charter (cost, risk, timeline) | PM (you) | 2‑page charter | Approved by CFO & CTO |
| 0.2 | Secure budget for migration effort | Finance Lead | Allocation of $80k (incl. contingency) | Budget sign‑off |
| 0.3 | Define success KPIs (latency, cost, availability) | SRE Lead | KPI doc (e.g., 99.95 % uptime, < 100 ms 95th‑pct latency) | KPI approved |
4.2 Phase 1 – Inventory & Dependency Mapping
| # | Action | Owner | Deliverable | Success Metric |
|---|--------|-------|-------------|----------------|
| 1.1 | Export Heroku app manifest (`heroku apps:info`, `heroku config`) | DevOps Engineer | JSON manifest per app | All env vars captured |
| 1.2 | Capture add‑on usage (Postgres, Redis, SendGrid) | DBA | List of connections, version, backup schedule | 100 % coverage |
| 1.3 | Map outbound API calls (third‑party, internal) | Backend Engineer | Sequence diagram + traffic profile | No unknown egress |
| 1.4 | Identify platform‑specific features (Heroku Scheduler, Dyno‑metadata) | Senior Engineer | Gap analysis doc | All gaps flagged |
4.3 Phase 2 – Architecture Design
| # | Action | Owner | Deliverable | Success Metric |
|---|--------|-------|-------------|----------------|
| 2.1 | Choose target (ECS vs Fly.io) – run cost model for 3‑yr horizon | PM + Finance | Decision matrix | Decision > 90 % confidence |
| 2.2 | Draft container architecture (Dockerfile, multi‑stage build) | Backend Engineer | Dockerfile repo + CI template | Build passes in CI 100 % |
| 2.3 | Define networking (VPC, subnets, security groups for ECS; Fly Regions for Fly.io) | SRE | Terraform modules / Fly.toml | Security audit passes |
| 2.4 | Design data migration strategy (snapshot, logical dump, CDC) | DBA | Migration runbook | Zero‑downtime plan ready |
4.4 Phase 3 – Proof‑of‑Concept (PoC)
| # | Action | Owner | Deliverable | Success Metric |
|---|--------|-------|-------------|----------------|
| 3.1 | Deploy a minimal “hello‑world” container to target platform | DevOps | Live endpoint (URL) | < 50 ms response, < 10 ms warm‑up |
| 3.2 | Run load test (k6) at 10 k req/min | QA | k6 report | Latency < 150 ms, error < 0.1 % |
| 3.3 | Validate logs & metrics pipeline (CloudWatch vs Fly‑Metrics) | SRE | Dashboard | 100 % coverage of key logs |
| 3.4 | Conduct security scan (Trivy, AWS Inspector) | SecOps | Scan report | No critical findings |
4.5 Phase 4 – Data Migration & Cut‑over
| # | Action | Owner | Deliverable | Success Metric |
|---|--------|-------|-------------|----------------|
| 4.1 | Provision target DB (RDS Aurora Serverless v2 for ECS, Fly Postgres for Fly.io) | DBA | DB endpoint | Replication lag < 5 s |
| 4.2 | Run initial bulk load (pg_dump/pg_restore or pglogical) | DBA | Data checksum match | Row count diff < 0.01 % |
| 4.3 | Switch read‑only mode on Heroku DB (maintenance window) | Ops Lead | Confirmation email | No writes for 30 min |
| 4.4 | Promote target DB (change DNS / env var) | DevOps | Production traffic redirected | 0 % error during switchover |
| 4.5 | Decommission Heroku dynos (scale to 0) | DevOps | Billing stopped | Heroku invoice $0 for next month |
4.6 Phase 5 – Post‑Migration Validation
| # | Action | Owner | Deliverable | Success Metric |
|---|--------|-------|-------------|----------------|
| 5.1 | Run synthetic monitoring (Pingdom,