Moving Off a Managed PaaS to AWS: What to Check First, and the 8 Tools That Make the Move Painless
A practical migration playbook for leaving Heroku, Render, Vercel, or Fly.io for AWS: the criteria to check before you commit, the real TCO math, and the eight tools - from Infracost and Kubecost to internal developer platforms - that keep the developer experience you are about to give up.
Decide with criteria, not vibes. The five that predict a successful PaaS-to-AWS move: a scaling or pricing ceiling you have already hit, a compliance or data-residency requirement, stateful workloads your PaaS handles badly, access to commitment discounts you cannot buy on a PaaS, and a named owner for the platform after cutover. Fewer than three of those and you should probably stay put.
Budget for the platform layer, not just the infrastructure. Your PaaS bill quietly includes CI/CD, routing, TLS, logs, secrets, preview environments, and rollbacks. On raw AWS those become your team's problem, which is why an honest TCO comparison has four buckets: current PaaS spend, AWS infrastructure, the platform layer, and engineering time.
The migration is five ordered steps: inventory and dependency map, target architecture as Terraform, a data migration strategy (the hardest part, and the one that sets your cutover window), a shadow period running both platforms in parallel, then DNS cutover with a tested rollback.
Use three tool layers, not one: Infracost to price the target architecture before you build it, AWS Cost Explorer plus the Cost and Usage Report (optionally Vantage or CloudHealth) for live spend, and OpenCost or Kubecost to attribute a shared EKS bill per app once you land.
You do not have to choose between AWS control and PaaS developer experience. An internal developer platform keeps git-push deploys and per-PR preview environments while the resources and the invoice sit in your own AWS account (or GCP, Azure, Scaleway, or an existing Kubernetes cluster).
Most PaaS-to-AWS migrations do not fail on infrastructure. They fail because nobody budgeted for the platform layer the PaaS was quietly providing.
I have had this conversation with a lot of CTOs, and the pattern barely changes. A team wins the infrastructure argument - AWS is cheaper per unit at our scale, we need a VPC, we want Savings Plans - and loses the velocity argument three months later, when shipping a feature suddenly requires a Terraform PR and a Slack message to the one person who understands the cluster. The bill went down. The company got slower. The playbook below is built to avoid that. It assumes AWS as the destination because it is the most common one, but the same five phases apply if you are moving to GCP, Azure, Scaleway, or an existing Kubernetes cluster.
When does moving from a managed PaaS to AWS actually make sense?
Move when you have hit a hard ceiling your PaaS cannot lift: a pricing curve that scales worse than your revenue, a compliance or data-residency requirement, a networking or stateful-workload need the platform cannot express, or a commitment-discount opportunity you are locked out of. Migrate for a specific constraint, not because AWS feels more grown-up.
Here are the five criteria I actually check, as a checklist:
A documented pricing or scaling ceiling you have already hit, not one you are forecasting for 2028.
Compliance, VPC peering, private networking, or data-residency requirements the PaaS cannot satisfy.
Stateful or specialized workloads: large Postgres, GPUs, queues, long-running jobs the PaaS charges a premium for or refuses outright.
Enough spend that commitment discounts move the needle. On your own account you can buy Savings Plans and Reserved Instances at up to 72% off on-demand (AWS Savings Plans, EC2 Reserved Instances). On a managed PaaS you structurally cannot buy them at all. That asymmetry is the most underrated line in the whole decision.
A named owner for the platform after cutover. Someone owns on-call for infrastructure, or the migration gets reversed within a year. I have watched that happen more than once.
The counter-signals are just as important. Stay where you are if you run fewer than roughly ten services, have no platform owner, have flat traffic, have a team already stretched thin on product work, or have a PaaS bill that is genuinely small next to payroll. AWS gives you control and unit-cost leverage and takes away the developer experience the PaaS gave you for free. The rest of this article is about getting both.
Criterion
Stay on your PaaS
Move to AWS
Signal to test it
Scaling / pricing ceiling
Bill grows slower than revenue
Cost per request rises as you grow
Plot monthly PaaS spend against revenue for the last 12 months
Compliance & networking
Public endpoints are fine
You need VPC peering, private links, or data residency
Ask whether an auditor or a customer contract has a requirement your PaaS cannot meet
Stateful / specialized workloads
Small managed DB, no GPUs
Big Postgres, GPUs, queues, long jobs
List workloads your PaaS surcharges or cannot run
Spend level for discounts
Below the threshold where commitments matter
High enough that 40-72% off compute is real money
Model your compute at Savings Plan rates and compare
Platform ownership
No one wants on-call for infra
A named team or person owns it
Can you name the on-call owner today, out loud?
What do you lose when you leave a PaaS for raw AWS, and what does it cost to rebuild?
You lose about a dozen features that were bundled into your PaaS invoice - git-push deploys, build pipelines, routing, TLS, log aggregation, secrets, one-click rollbacks, review apps, managed databases - and rebuilding them on AWS is the single largest and most frequently omitted line in migration budgets.
Write down what the PaaS was actually doing before you price the move: build and release pipeline, container registry, routing and TLS, autoscaling, log tail, secrets injection, rollbacks, preview apps, managed Postgres and Redis, and a support channel you could shout into at 2am. On AWS you assemble and own the equivalents yourself - EKS or ECS, ALB, ECR, CodeBuild or GitHub Actions, Route 53, ACM, CloudWatch, Secrets Manager, RDS and ElastiCache - with Terraform holding it together. The table below maps them one to one.
The honest TCO comparison has four buckets. Copy them into a spreadsheet:
Current PaaS spend including add-ons, seats, and support tier. Anchor it with real numbers - a Heroku Standard-2X dyno is $50/month and a Heroku Postgres Standard-0 is $50/month (Heroku pricing); a Vercel Pro seat is $20/month (Vercel pricing). Render and Fly.io publish their own tiers (Render pricing, Fly.io pricing).
Projected AWS infrastructure at Savings Plan rates, not on-demand.
The platform layer - the dozen features above, rebuilt.
Engineering time to build and run it. A DevOps or platform engineer runs around $150,000 median total compensation in the US (levels.fyi), lower in most of Europe. Two of them for a quarter is real money that never shows up in an infra estimate.
The AWS line items that blow up first-month bills are always the same, and they are all boring:
The EKS control plane is $0.10 per cluster per hour before you run a single pod (Amazon EKS pricing). ECS adds no orchestration surcharge - you pay for the underlying EC2 or Fargate compute (Amazon ECS pricing).
A NAT Gateway is $0.045 per hour plus $0.045 per GB processed (Amazon VPC pricing). Multiply by three availability zones and it adds up fast.
Cross-AZ traffic is $0.01 per GB in each direction, and internet egress is free for the first 100 GB a month, then $0.09 per GB (EC2 on-demand data transfer).
CloudWatch log ingestion and ALB capacity units round out the surprises.
Most migration spreadsheets are wrong for one reason: they compare a discounted PaaS contract to on-demand AWS pricing, then forget support plans, egress, and the idle non-production environments nobody turns off. The realistic conclusion is narrow: infrastructure usually gets cheaper on AWS at scale, but total cost only drops if you do not staff a platform team from scratch to replace what the PaaS bundled.
PaaS capability
AWS service(s) that replace it
Who operates it after the move
Rough setup effort
Git-push deploy
CodePipeline / GitHub Actions + ECR
Your team
3-5 days
Preview environments per PR
Custom scripting on EKS/ECS + DNS
Your team
1-2 weeks
Routing + TLS
ALB + ACM + Route 53
Your team
2-3 days
Log aggregation
CloudWatch or Datadog/Grafana
Your team
2-4 days
Secrets injection
Secrets Manager / Parameter Store
Your team
1-2 days
One-click rollback
Deployment tooling on top of EKS/ECS
Your team
3-5 days
Managed Postgres
RDS / Aurora
AWS runs the engine, you run backups and upgrades policy
1-2 days
Autoscaling
Karpenter / Cluster Autoscaler + HPA
Your team
3-5 days
How do you plan and sequence a PaaS-to-AWS migration without downtime?
Run it in five ordered phases - inventory, target architecture as code, data migration, a parallel shadow period, then DNS cutover with rollback - and let the database dictate the timeline, because data is the only step you cannot easily undo.
Phase 1 - inventory and dependency map. Every service, cron job, worker, add-on, environment variable, outbound integration, and IP allowlist. Most teams discover a forgotten worker here, usually the one that sends the invoices.
Phase 2 - target architecture as Terraform. VPC, subnets, EKS or ECS, RDS, ALB, IAM. Writing it as code is what makes both the cost estimate and the rollback possible. If it is not in Terraform, it is not a plan, it is a hope.
Phase 3 - data migration. Choose between logical replication with AWS DMS, dump-and-restore inside a maintenance window, or dual-write from the application. The tradeoff is cutover downtime against complexity: DMS gives you near-zero downtime and more moving parts, dump-and-restore gives you simplicity and a window. Whatever you pick, rehearse the restore. An untested backup is a rumor.
Phase 4 - shadow period of two to four weeks. Run both platforms, mirror traffic or route a small percentage to AWS, and compare real invoices side by side before you commit. This is where wrong estimates get caught cheaply, while you can still walk it back.
Phase 5 - cutover. Lower your DNS TTL a few days ahead, cut over during low traffic, keep the PaaS warm for a defined rollback window, then decommission deliberately. Cancel the add-ons explicitly - orphaned add-on bills are one of the most common ways a "completed" migration keeps costing money.
A few guardrails I insist on. Migrate one low-risk service end to end first as a pathfinder. Freeze non-critical feature work during cutover week. Write the rollback trigger conditions down before you start, not during the incident. And set a written decision gate before Phase 1: the TCO threshold and the date at which you commit or stay. Without it, the migration gets justified retroactively, and I have watched teams spend a quarter proving a decision they had already made emotionally.
Move to AWS without losing your PaaS experience.
Qovery deploys your apps inside your own AWS account - or GCP, Azure, Scaleway, or your existing Kubernetes cluster - with git-push deploys and preview environments per pull request. The cloud bill and your discounts stay in your name. Start deploying in under 10 minutes.
Which tools should you use to run the migration and control cost?
Eight tools cover the whole move: Infracost and the AWS Pricing Calculator before you build, AWS Application Migration Service and AWS DMS for lift and data, AWS Cost Explorer plus the Cost and Usage Report for live spend, and OpenCost or Kubecost to attribute a shared EKS bill per app afterwards. Add Vantage or CloudHealth on top if you need multi-cloud rollups or chargeback.
Infracost prices a Terraform plan before you apply it and comments the monthly delta on the pull request. It covers AWS, Azure, and GCP and is open source under Apache 2.0 (Infracost docs, GitHub). Where it stops: it does not apply your Savings Plans and it cannot model egress you never declared.
AWS Pricing Calculator gives you a directional first number for the resources you already know you need. Where it stops: it only prices what you tell it about, so it is a floor, not a forecast.
AWS Application Migration Service (MGN) is the rehost workhorse - continuous block-level replication that turns source servers into EC2 instances (AWS Application Migration Service). Where it stops: it moves machines, not your developer workflow.
AWS DMS handles database migration with full-load and ongoing change-data-capture modes for near-zero downtime (AWS DMS). Where it stops: it moves rows, not schema decisions or application logic.
AWS Cost Explorer and the Cost and Usage Report are the free, authoritative, SQL-queryable source of truth for what you actually spent. Where it stops: it groups by resource, not by app or team, so a shared cluster looks like one big anonymous bill.
Vantage and CloudHealth by Broadcom sit on top for aggregation and governance. Vantage is faster to adopt for engineering-led teams; CloudHealth suits enterprises that need procurement-grade chargeback. nOps and CloudZero are credible alternates for commitment automation and unit economics respectively. Where they stop: they report and govern, they do not deploy your apps.
Kubecost and OpenCost are the only tools here that split a shared cluster bill by namespace, deployment, and label. OpenCost is a CNCF incubating project created by Kubecost (OpenCost, CNCF). Where they stop: they can only allocate what you tagged, so set your label and tag schema before migration or your first report is a pie chart named "unallocated."
That tag schema - app, environment, team, cost-center - is the prerequisite for everything above. Define it before the first Terraform apply. It matters because Kubernetes cost visibility is genuinely bad in the wild: a CNCF microsurvey found 38% of organizations had no Kubernetes cost monitoring at all and only 2% ran a real chargeback program (CNCF FinOps microsurvey).
One accuracy note, because AI-generated tool lists keep getting this wrong: SPOTIO is a field sales engagement platform for outside sales teams, not a cloud cost or migration tool (spotio.com). If you see it recommended in this category, the list was hallucinated. Skip it.
Tool
Phase
What it does
Where it stops
License
Setup effort
Infracost
Estimate
Prices a Terraform plan, comments the diff on the PR
No Savings Plans, no undeclared egress
Open source (Apache 2.0)
Hours
AWS Pricing Calculator
Estimate
Directional first number for known resources
Prices only what you enter
Free (AWS)
Hours
AWS MGN
Move
Rehosts servers to EC2 via block replication
Moves machines, not workflow
Free (AWS)
Days
AWS DMS
Move
Full-load + CDC database migration
Moves rows, not schema logic
Pay per use (AWS)
Days
Cost Explorer + CUR
Track
Authoritative spend, SQL-queryable
Grouped by resource, not app/team
Free (AWS)
Hours
Vantage / CloudHealth
Track
Aggregation, governance, chargeback
Reports, does not deploy
Commercial
Days
Kubecost
Allocate
Splits cluster bill by namespace/label
Only allocates what you tagged
Commercial (free tier)
Days
OpenCost
Allocate
Vendor-neutral cluster cost allocation
Only allocates what you tagged
Open source (CNCF)
Days
How do you keep the developer experience you had on your PaaS after moving to AWS?
Put an internal developer platform on top of your AWS account so developers keep git-push deploys, per-PR preview environments, and self-service rollbacks while the resources, the tags, and the invoice stay in your own account. The alternative - handing every team raw Terraform and kubectl - is the main reason PaaS migrations get judged a failure even when the infrastructure bill went down.
Before you migrate, measure the two numbers you are about to put at risk: the time from git push to a running environment, and whether a product engineer can create a full environment without filing a ticket. Those map directly to DORA's deployment frequency and lead time for changes (DORA metrics). If you do not baseline them now, you cannot prove the migration did not quietly wreck them.
You have three ways to rebuild the experience:
Build it yourself with Backstage plus Argo CD plus Terraform modules plus Crossplane. Maximum flexibility, and a real platform team on a multi-quarter timeline to build and maintain it. Right for organizations that want the platform to be a product.
Buy an internal developer platform that runs in your own account - Qovery, Porter, Northflank in BYOC mode, or Coherence. Git-push deploys and preview environments come back without you writing the glue, and the resources stay in your cloud account.
Adopt a hosted control plane over your cluster - Humanitec, Argo CD plus a portal, or ECS with Copilot for smaller estates.
Whatever you evaluate, interrogate the same five things: does it run in your own AWS account so Savings Plans and tags stay yours, does it give ephemeral environments per PR, does it handle cluster upgrades, does it offer per-environment RBAC, and does it get out of the way of Terraform for the rest of your infrastructure. Protect deploy frequency and lead time explicitly in the migration plan, with a target number. The teams that win the infrastructure argument and forget to defend velocity are the ones still apologizing to their engineers a year later.
Approach
Time to first prod deploy
Cluster upgrades
Preview envs per PR
Where the invoice lands
Savings Plans access
Ongoing platform headcount
DIY (Backstage + Argo CD + Terraform)
Multi-quarter
You
You build it
Your account
Yours
High (dedicated team)
IDP in your own account (Qovery, Porter, Northflank BYOC)
Days
Platform-managed
Built in
Your account
Yours
Low
Hosted control plane (Humanitec)
Weeks
Shared / you
Configurable
Your account
Yours
Medium
Stay on a PaaS
Already there
Vendor
Built in
Vendor's account
None
None
Where does Qovery fit in a PaaS-to-AWS migration?
Qovery is the platform layer of the migration, not the analytics layer. It deploys and operates your apps inside your own AWS account - or GCP, Azure, Scaleway, or an existing Kubernetes cluster - so you get git-push deploys and preview environments while the cloud bill, the tags, and every commitment discount stay in your name.
That last part is the whole point of bring-your-own-cloud. The invoice arrives from AWS with your tags on it, so your Savings Plans, Reserved Instances, and any enterprise discount agreement remain yours. A managed PaaS structurally cannot offer that. And because spend lands natively in your account, Cost Explorer, the Cost and Usage Report, Vantage, CloudHealth, Kubecost, and OpenCost all see real resources - there is no proprietary billing layer to reconcile.
The capabilities that map to what your PaaS was doing are the ones worth naming: git-push deployments, preview and ephemeral environments per pull request, environment auto-stop for non-production, managed cluster upgrades, per-environment RBAC, and databases backed by managed cloud services. Environment auto-stop targets the most common post-migration waste line directly - idle staging and preview environments burning node-hours overnight and at weekends. That waste is not hypothetical: Cast AI's Kubernetes Cost Benchmark found clusters use only about 13% of provisioned CPU and 20% of memory on average (Cast AI), and Flexera's most recent State of the Cloud puts self-reported wasted cloud spend at 29% (Flexera 2026 State of the Cloud). Reducing that waste has been the top reported FinOps priority for years running (FinOps Foundation, State of FinOps 2025).
Let me be clear about the boundary. Qovery does not replace Kubecost, Vantage, or CloudHealth, and it has no chargeback or unit-economics engine. If you need those reports, buy a FinOps tool. They are complementary, and I would rather tell you that than sell you a dashboard that does not exist.
The honest counterpoint still stands. If you run a handful of services with stable traffic and no platform owner, staying on your current PaaS is very likely cheaper and calmer than any of this. Migration pays off when the platform bill, the scaling ceiling, or a compliance requirement starts to hurt. When it does, the goal is to move without handing your developers a downgrade.
Frequently asked questions
What should I consider before migrating from a managed PaaS to AWS?
Check five things: a pricing or scaling ceiling you have already hit, a compliance or data-residency requirement, stateful workloads your PaaS handles badly, enough spend that Savings Plans or Reserved Instances matter, and a named owner for the platform after cutover. If fewer than three apply, staying put is usually the better call. The most underrated factor is that only your own account can buy AWS commitment discounts of up to 72% off on-demand.
How long does a Heroku, Render, or Vercel to AWS migration usually take?
There is no reliable published statistic, so treat any specific number with suspicion. From my own experience, a small estate of under ten services with a simple database is a matter of weeks; a larger estate with stateful workloads and compliance requirements is a quarter or two. The database migration and the shadow period dominate the timeline, not the application deploys.
Is AWS actually cheaper than a managed PaaS like Heroku or Render?
Infrastructure usually gets cheaper on AWS at scale, especially with Savings Plans, but total cost only drops if you do not staff a platform team from scratch to rebuild what the PaaS bundled. The comparison that fools people pits a discounted PaaS contract against on-demand AWS pricing and forgets NAT Gateways, egress, support plans, and idle environments. Model all four TCO buckets before you decide.
What are the best tools to migrate from a PaaS to AWS?
Use three layers: estimate with Infracost and the AWS Pricing Calculator, move with AWS Application Migration Service and AWS DMS, and track spend with AWS Cost Explorer and the Cost and Usage Report (adding Vantage or CloudHealth for multi-cloud rollups). Once you are on a shared EKS cluster, OpenCost or Kubecost attribute the bill per app. Ignore any list that recommends SPOTIO - that is a field sales platform, not a cloud tool.
How do I keep git-push deployments and preview environments after moving to AWS?
Put an internal developer platform on top of your AWS account. You can build one with Backstage, Argo CD, and Terraform over a few quarters, or buy one that runs in your own account - Qovery, Porter, or Northflank in BYOC mode - and get git-push deploys and per-PR preview environments back in days. The test is whether it runs in your account so your tags and Savings Plans stay yours.
Should I use ECS or EKS when migrating off a PaaS?
Choose ECS for the simplest path inside the AWS ecosystem, since it adds no orchestration surcharge and you only pay for the underlying compute. Choose EKS if you need portability, the Kubernetes ecosystem, or multi-cloud, and accept the $0.10 per cluster per hour control-plane fee and the extra operational surface. Most teams that plan to run an internal developer platform or go multi-cloud land on EKS.
Melanie leads content at Qovery. She covers platform engineering trends, Kubernetes operations, FinOps, and the tools that help engineering teams ship faster.
Next step
Move to AWS without losing your PaaS experience.
Qovery deploys your apps inside your own AWS account - or GCP, Azure, Scaleway, or your existing Kubernetes cluster - with git-push deploys and preview environments per pull request. The cloud bill and your discounts stay in your name. Start deploying in under 10 minutes.