postgres to aurora · homogeneous migration · 2026

PostgreSQL to Aurora PostgreSQL — four methods, one near-zero-downtime cutover.

Aurora PostgreSQL speaks the same wire protocol and runs the same SQL as the Postgres you already have, so this is a homogeneous migration with no schema conversion. The real work is extension and version compatibility, picking the right move-the-data method (snapshot, logical replication, RDS read-replica promotion, or DMS), and rehearsing a cutover you can roll back. This page walks all four, with honest downtime and cost numbers, and when a vetted partner can file MAP funding for the move (only when your Postgres runs outside AWS today).

schema conversion
none
cutover downtime
sec–min
vs RDS PG list
~same/core
TL;DR
  • Postgres → Aurora PostgreSQL is homogeneous: same engine, wire protocol, SQL, and drivers. No Schema Conversion Tool step and no application rewrite — your connection string changes and very little else. The risk lives in three places: extension support, the source-vs-target major version, and the cutover.
  • Four methods, in rising complexity and falling downtime: (1) snapshot/restore or pg_dump/pg_restore — simplest, needs a window; (2) Aurora read replica from an existing RDS PostgreSQL instance, then promote — near-zero, RDS-source only; (3) native PostgreSQL logical replication — engine-native CDC from any Postgres; (4) AWS DMS with CDC — near-zero from anywhere, including self-managed and other clouds. Most RDS sources use method 2 or 3; DMS handles self-managed or off-AWS.
  • On cost, Aurora is roughly comparable to RDS PostgreSQL per vCPU-hour and storage-GB, bills I/O differently (pay-per-request, or Aurora I/O-Optimized for I/O-heavy loads), bundles a faster distributed storage layer, and adds Serverless v2 for spiky load. CloudRoute can match you with a vetted AWS partner who runs the migration. MAP (Migration Acceleration Program) funding is for moves onto AWS: a Heroku, Cloud SQL or self-managed source outside AWS can qualify, and the partner files it if so. A move from RDS PostgreSQL stays inside AWS, so it is not a MAP migration.
context

IWhy move Postgres to Aurora PostgreSQL at all

Aurora PostgreSQL is a PostgreSQL-compatible engine that AWS re-built on a purpose-designed distributed storage layer. You keep PostgreSQL — the SQL, the extensions, the drivers, the ecosystem — and swap the storage and replication internals for something built to scale reads, survive failures, and recover faster.

The single most important fact about this migration: it is homogeneous. Aurora PostgreSQL is wire-compatible with community PostgreSQL, so the same psql client, the same JDBC/psycopg/pgx drivers, the same ORM, and the same SQL all work unchanged. There is no schema conversion, no datatype remapping, no PL/pgSQL rewrite. That is the entire reason a Postgres→Aurora move is an order of magnitude less risky than a heterogeneous move like Oracle→Aurora or SQL Server→Aurora, where the AWS Schema Conversion Tool (SCT) and weeks of stored-procedure rework are the main event.

The reasons teams make the move cluster into four buckets. Read scaling: up to 15 low-latency read replicas share one copy of the storage volume, so adding a replica does not duplicate the data and replica lag is typically single-digit milliseconds rather than the seconds RDS streaming replicas can show under load. Durability and recovery: data is written six ways across three Availability Zones, storage self-heals, and failover to a replica is usually 30 seconds or less versus the one-to-two minutes typical of RDS Multi-AZ. Storage that manages itself: the volume auto-grows in 10 GB increments to 128 TiB with no pre-provisioning and no resize downtime.

The fourth bucket is operational economics: Aurora separates compute from a storage layer you never size, supports Serverless v2 for spiky or unpredictable load (fine-grained capacity that can sit at a low floor between bursts), offers Global Database for sub-second cross-region replication, and clones a multi-terabyte database in minutes via copy-on-write for test environments. None of these change your application code.

The honest counterpoint, stated up front: if your database is small, steady, and single-AZ-tolerant, plain RDS PostgreSQL may be cheaper and is perfectly fine — Aurora earns its keep when you need the read fan-out, the faster failover, the self-managing storage, or Serverless v2 elasticity. Section VII lays the costs out side by side so the decision is made on numbers, not vibes.

the real gotchas

IIExtension and version compatibility — where homogeneous migrations actually bite

Because the SQL ports cleanly, the genuine compatibility surface is narrow but sharp: which PostgreSQL extensions you depend on, which major version you are on, and a short list of behaviours Aurora handles differently from community Postgres.

Aurora PostgreSQL ships a large set of supported extensions — pgvector, PostGIS, pg_stat_statements, pg_partman, pg_cron, hstore, citext, uuid-ossp, the postgres_fdw / dblink family, pglogical, and many more — but the supported list and the exact supported version of each extension are tied to the Aurora PostgreSQL engine version. The first task in any real assessment is to enumerate what the source actually uses (query pg_extension and check what your application loads) and confirm each one is available, at a compatible version, on the target Aurora engine. This is the number-one source of late surprises.

Two classes of extension need explicit attention. First, anything that depends on loading arbitrary C libraries or shared_preload_libraries that a managed engine does not allow — heavily custom or niche third-party extensions can be unsupported on both RDS and Aurora, and that is a finding you want in week one, not at cutover. Second, version-sensitive extensions: pgvector in particular has moved quickly (index types and operators have evolved across releases), so if you run vector search you want source and target on versions whose pgvector behaviour matches, or plan a controlled reindex.

Version strategy matters because logical replication and DMS CDC both have version expectations. Native PostgreSQL logical replication generally wants the source on PostgreSQL 10+ (publications/subscriptions) and is smoothest when source and target majors are close — replicating into a newer major is usually fine, the wrong direction is not. The clean approach is to land on Aurora at a major version equal to or one step above the source, validate, then do any major-version upgrade as a separate, well-understood operation afterwards rather than combining a platform move and a big version jump in one cutover.

A few behavioural differences are worth knowing but are rarely blockers: Aurora manages or ignores storage/replication GUCs that have no meaning on its architecture (you do not tune full_page_writes or WAL archiving as you would on self-managed Postgres); parameter and minor-version management happens through DB cluster and instance parameter groups, not postgresql.conf; and you get the rds_superuser role rather than raw SUPERUSER. If your app or migration tooling assumes SUPERUSER or direct filesystem/WAL access, that assumption needs revisiting — and it needs revisiting for RDS too.

do this first

Before choosing a method, run the inventory: SELECT extname, extversion FROM pg_extension; on every source database, list any shared_preload_libraries, note the exact source major.minor version, and confirm each extension is supported at a compatible version on the target Aurora PostgreSQL engine. Extension/version mismatches — not data movement — are what derail homogeneous migrations.

four methods

IIIThe four ways to move the data — and which one fits

All four land you on the same place: an Aurora PostgreSQL cluster running your schema and data. They differ on downtime, on which sources they support, and on how much rehearsal they need. Pick on those three axes.

The routing question CloudRoute (and any competent partner) asks first is: where does the source live, and how much downtime can you tolerate at cutover? Those two answers narrow four methods to one or two. Below, in rising order of complexity.

Method 1 — Snapshot/restore or pg_dump → pg_restore (simplest, needs a window)

How: For an RDS PostgreSQL source, take an RDS snapshot and restore it directly as an Aurora PostgreSQL cluster — AWS migrates the data for you. For self-managed or off-AWS Postgres, run pg_dump and restore into Aurora with pg_restore (parallelized with -j). Either way the database is offline for writes from the moment you take the consistent copy until the app is pointed at Aurora.

Downtime: equal to copy + restore + validation time — minutes for a few GB, hours for hundreds of GB to a few TB.

Best for: small-to-mid databases, dev/test environments, and any workload that can take a planned window. Lowest complexity, lowest risk — the default when a short outage is fine.

Method 2 — Aurora read replica from RDS PostgreSQL, then promote (near-zero, RDS-source only)

How: If the source is already RDS PostgreSQL, create an Aurora PostgreSQL Read Replica of it. AWS seeds Aurora from the RDS data and keeps it in sync. When lag reaches zero, you stop writes briefly, let Aurora catch up, promote the replica to a standalone cluster, and repoint the app.

Downtime: seconds to a couple of minutes — only the brief quiesce-and-promote window, not the data copy.

Best for: the common case of an RDS PostgreSQL estate moving to Aurora. It is the cleanest near-zero path because AWS manages the seeding and sync end to end. The catch: the source must be RDS PostgreSQL (not self-managed or other-cloud) at a major version Aurora supports as a replication source.

Method 3 — Native PostgreSQL logical replication (engine-native CDC, any Postgres)

How: Use PostgreSQL's built-in logical replication (a publication on the source, a subscription on Aurora) — or pglogical for more control. Load the initial copy, then logical replication streams ongoing changes into Aurora until you flip. This is Postgres replicating to Postgres on the engine's own machinery, so it is high-fidelity for standard tables.

Downtime: near-zero — a short cutover once the subscription is caught up.

Best for: near-zero moves from any Postgres (self-managed on EC2/on-prem, Heroku/Crunchy/Supabase, Cloud SQL for PostgreSQL) where you want to avoid a separate migration service. Constraints: it does not replicate sequences (advance them at cutover), large objects and some DDL need handling, every replicated table needs a primary key or a defined REPLICA IDENTITY, and it wants the source on a modern major (10+).

Method 4 — AWS DMS with CDC (near-zero from anywhere, most flexible)

How: AWS Database Migration Service does a full load of existing data, then change data capture (CDC) to replicate ongoing writes until cutover. For homogeneous Postgres→Postgres there is no Schema Conversion Tool step — the schema is already compatible (create it with pg_dump --schema-only or via your migration plan), and DMS can use PostgreSQL logical replication under the hood.

Downtime: near-zero — flip when CDC latency is at or near zero.

Best for: sources that are self-managed, on another cloud, or otherwise not RDS — and migrations where you want one managed service to orchestrate full-load + CDC, monitor latency, validate row counts, and run several databases in parallel. The usual choice when method 2 is unavailable and you do not want to hand-run logical replication. Caveats: DMS moves table data well but is not a complete schema/constraint/sequence tool by itself, wide or LOB-heavy tables need tuning, and you should run DMS data validation before trusting the cutover.

the cutover

IVCutover, validation, and rollback — the part that actually decides success

For the three near-zero methods, the migration is 90% waiting for sync and 10% a tightly choreographed cutover. The discipline that separates a clean flip from an incident is the runbook around that window.

A sound cutover sequence looks the same regardless of which CDC method you used. Let the target reach steady-state with replication latency at or near zero and hold it there under real production load long enough to trust it — a few days to a couple of weeks for a busy database. Validate continuously while you wait: compare row counts per table, checksum or sample critical tables, point a read-only copy of the app or your analytics queries at Aurora, and watch the DMS or logical-replication lag metrics.

At the flip: drain writes on the source (brief read-only/maintenance mode), let replication drain the last transactions to zero latency, advance any sequences on the target to match the source (logical replication and DMS do not carry sequence values automatically), run final integrity checks, then repoint the application to the Aurora cluster endpoint. A DNS CNAME or a centrally-managed connection string in front of the endpoint makes both the flip and the rollback a single change rather than a redeploy.

The rollback plan is non-negotiable and the reason senior teams sleep through cutover night. Keep the source intact and writable-on-demand until you have soaked on Aurora through at least one full business cycle. If something is wrong post-cutover — a missed extension behaviour, a query-plan regression, an app assumption you did not catch — repointing back to the source must be a sub-minute operation. The risk window is the gap between "writes now go to Aurora" and "we are confident enough to decommission the source"; design it to be cheap to reverse, not heroic.

Two recurring gotchas worth pre-empting. First, connections: if you front Aurora with RDS Proxy or a pooler, validate it before cutover — connection-storm behaviour and failover semantics differ from a single RDS instance. Second, statistics: run ANALYZE on the Aurora cluster after the load, because a freshly loaded database with stale stats can produce alarming query plans that resolve the moment statistics are current — a surprise best met during the soak, not during the flip.

sizing for spiky load

VProvisioned vs Aurora Serverless v2 — sizing the target

Aurora gives you two ways to run the same PostgreSQL-compatible engine: classic provisioned instances (you pick the instance class) or Serverless v2 (capacity scales in fine-grained increments between a floor and a ceiling you set). The right choice depends on how predictable your load is.

Provisioned Aurora is the default for steady, predictable workloads. You size the writer and readers to your baseline, you pay for that capacity continuously, and you get the most predictable per-hour cost. If your database runs at a fairly constant utilization all day, provisioned is usually the cheaper and simpler choice — and you can still attach Serverless v2 readers later if a reporting workload needs to flex independently.

Aurora Serverless v2 measures capacity in Aurora Capacity Units (ACUs) and scales them up and down in small steps in response to load, between a minimum and maximum you configure. It shines for workloads that are spiky, bursty, or unpredictable — a SaaS app with sharp business-hours peaks and quiet nights, dev/test/staging environments that should idle cheaply, new products without a known traffic profile, and multi-tenant fleets where individual databases have very different and unpredictable demand. You pay for the capacity actually consumed at fine granularity, so you stop paying for headroom you only need at peak.

The practical pattern for a migration is to land on the shape that matches the workload, not to over-think it: steady production → provisioned, sized to baseline with a couple of readers for fan-out; spiky or unknown production → Serverless v2 with a sensible floor and a ceiling above your worst peak; non-prod → Serverless v2 with a low floor so it costs little when idle. A frequent and effective mix is a provisioned writer for the predictable baseline plus Serverless v2 readers that absorb bursty read traffic. Whatever you choose, set the minimum capacity deliberately — too low a floor on a latency-sensitive production database can mean a cold scale-up exactly when traffic arrives.

end to end

VIA near-zero-downtime migration, step by step

Concretely, here is the shape of a logical-replication or DMS CDC migration from a busy production PostgreSQL database to Aurora PostgreSQL, the way a partner runs it.

1 — Inventory & compatibility. Enumerate every source database, its exact major.minor version, every extension (extname/extversion) and any shared_preload_libraries, the workload shape (read/write ratio, peak concurrency, largest tables, LOB usage), and every application connection string. Confirm each extension is supported at a compatible version on the target Aurora engine. This is the step that prevents cutover-night surprises.

2 — Target design. Choose the Aurora PostgreSQL engine version (equal to or one major above the source), provisioned vs Serverless v2, writer/reader topology, the parameter group, networking (VPC, subnets, security groups), and whether RDS Proxy fronts the cluster. Provision the cluster and apply the parameter group.

3 — Schema load. Create the target schema (pg_dump --schema-only → restore, or your IaC/migrations), install required extensions on Aurora at matching versions, and confirm every replicated table has a primary key or a defined REPLICA IDENTITY so CDC can track row changes.

4 — Initial load + CDC. Full-load the existing data (DMS full-load, or initial copy + logical-replication subscription), then start CDC so ongoing writes stream to Aurora. Monitor replication latency until it sits at or near zero.

5 — Soak & validate. Hold the target in sync under real production load for days-to-weeks. Compare row counts and checksums, point read-only traffic and analytics at Aurora, run ANALYZE, and watch lag and error metrics. Fix any extension-behaviour or query-plan surprises now, with the source still authoritative.

6 — Cutover. Quiesce writes on the source, drain the last transactions to zero latency, advance sequences on the target, run final integrity checks, and repoint the application (DNS/CNAME or central connection string) to the Aurora endpoint. Total write-downtime: seconds to a couple of minutes.

7 — Stabilize & decommission. Keep the old source intact and reversible through at least one full business cycle. Once Aurora is proven, retire the source, finalize backups/retention and monitoring on Aurora, and right-size capacity based on observed load.

the money

VIICost: Aurora PostgreSQL vs RDS PostgreSQL vs self-managed

The honest cost story is that Aurora is roughly comparable to RDS PostgreSQL on compute and storage per unit, prices I/O differently, and removes a large slice of the human-time and risk cost that dominates self-managed Postgres on EC2 or on-prem. Decide on total cost, not the per-hour sticker.

On compute, Aurora and RDS PostgreSQL are in the same ballpark per vCPU-hour for comparable classes; Aurora often carries a modest premium that buys the distributed storage layer, faster failover, and read fan-out. On storage, both bill per GB-month, but Aurora's volume is self-managing (auto-grows, no pre-provisioning, no resize downtime) while RDS storage is pre-provisioned. The dimension people miss is I/O: Aurora bills storage I/O pay-per-request by default, and offers Aurora I/O-Optimized — a configuration that removes per-request I/O charges in exchange for higher compute/storage rates, which is cheaper for I/O-intensive workloads (often a meaningful fraction of Aurora spend) and worth modelling explicitly.

Against self-managed PostgreSQL on EC2 or on-prem, the instance can look cheaper on paper — until you add the parts you now own: building and testing HA and failover, patching and minor-version upgrades, backup/restore and PITR engineering, storage scaling and its downtime, replication, monitoring, and on-call when any of it breaks at 3am. Aurora and RDS fold those into the managed price. For most teams the self-managed "savings" are eaten by engineering time and the risk of an HA story that has never actually been failover-tested.

Decide by modelling 12-month total cost on your real numbers — instance class, storage GB, observed I/O, replica count, plus a realistic line for the DBA/SRE hours self-management consumes — across all three options, factoring Serverless v2 if your load is spiky (a bursty workload that idles at night can land well below a provisioned instance sized for peak). The table below frames the axes; the next section is where the cost can drop to near-zero for the migration itself.

the CloudRoute mechanism

VIIIWho runs it, and when MAP funding applies

Even though Postgres to Aurora is technically clean, most teams have not run a near-zero-downtime production cutover with a tested rollback before, and they want it run by someone who has. CloudRoute matches you with that partner. Whether AWS funds the move depends on where your Postgres runs today.

CloudRoute is a routing layer, not the migrator. You describe the source (RDS / self-managed / Heroku / Cloud SQL), the database size and workload, your downtime tolerance, and your timeline; CloudRoute matches you to a vetted AWS partner with a documented PostgreSQL→Aurora track record and the relevant tier (Advanced or Premier for MAP-scale engagements), in your region. The partner runs the inventory, target design, data-movement method, soak, cutover, and rollback plan.

The funding route is the AWS Migration Acceleration Program (MAP). MAP has three phases: Assess (readiness and a TCO model; the extension and version inventory and the method choice live here), Mobilize (landing zone, pilot, runbook) and Migrate and Modernize (production cutover). MAP is for moves onto AWS, so a source on Heroku, Cloud SQL, another cloud or your own servers can qualify. Your matched partner files the MAP request when the migration qualifies, and AWS decides. For startups, partner-filed funding is typically $50K to $150K. Depends on the workload; AWS approves.

The honest framing, stated plainly: a move from RDS PostgreSQL to Aurora stays inside AWS, so it is not a MAP migration. A single small database from outside AWS may also be too small on its own; it has a better chance as part of a broader move to AWS. If the Aurora move comes with new work on AWS, such as a new product or a new customer, ask the partner about incremental workload (IW) funding. Where no funding applies, a vetted partner still de-risks the cutover. CloudRoute is free for you either way. Partners pay CloudRoute a monthly membership plus 10% of AWS-approved funding.

who pays for what

MAP funding applies only to a qualifying move onto AWS, and AWS approves it. It offsets the migration work, not the running Aurora cluster afterwards. A move from RDS PostgreSQL is not a MAP migration, so plan to pay the partner for that work. CloudRoute never charges you: partners pay CloudRoute a monthly membership plus 10% of AWS-approved funding.

side by side

Aurora PostgreSQL vs RDS PostgreSQL vs self-managed PostgreSQL

Same engine, three operating models. Aurora and RDS are both managed PostgreSQL-compatible services; self-managed is PostgreSQL you run yourself on EC2 or on-prem. The differences are in storage, scaling, failover, and how much you operate by hand.

DimensionRDS PostgreSQLAurora PostgreSQLSelf-managed (EC2 / on-prem)
EngineCommunity PostgreSQL (managed)PostgreSQL-compatible, AWS storage engineCommunity PostgreSQL (you run it)
Schema conversion to migrateNone (already Postgres)None — homogeneous, wire-compatibleNone (it is Postgres)
StoragePre-provisioned EBS; resize is an operationAuto-grows to 128 TiB; 6 copies / 3 AZs; self-healingYou size, scale, and protect disks yourself
Read replicasUp to 5 streaming replicas (own copies)Up to 15 replicas sharing one volume; ms-level lagYou build and manage streaming replication
FailoverMulti-AZ ~1–2 minTypically ≤30s to a replicaWhatever you build and have actually tested
Elastic capacityFixed instance classProvisioned or Serverless v2 (fine-grained autoscale)Manual rightsizing / re-provisioning
I/O billingBundled in provisioned storagePay-per-request or Aurora I/O-OptimizedYour own disk/IOPS spend
Ops burden (HA, patching, backups, on-call)Low — AWS-managedLow — AWS-managedHigh — you own all of it
Best fitSteady, modest, single-region PostgresRead fan-out, fast failover, spiky load, scaleFull control / specific OS-level needs / niche extensions
Per-vCPU and per-GB pricing is roughly comparable between RDS and Aurora; Aurora prices I/O separately (or via I/O-Optimized) and bundles a faster, self-managing storage layer. Self-managed often looks cheapest on the instance line and is rarely cheapest once HA, patching, backups, scaling, and on-call time are costed in. Model 12-month total cost on your own numbers.
ready to scope the cutover?
Get matched with a partner who runs the Postgres→Aurora migration for you
Get matched free with a vetted AWS partner who can file it
how a match works

How a match works (example)

  1. You tell us about the work

    You fill in a short form: what you run today, what you want to move, test or build, your stage and your region.

  2. We pick one partner

    We read your answers and pick one vetted AWS consulting partner that fits the work, the stack and the region. We reply within 24 hours; your matched partner reaches out within 5 business days.

  3. The partner checks MAP funding

    Your matched partner scopes the migration with you. Then it checks whether the move qualifies for MAP (Migration Acceleration Program) funding. MAP is for teams that are not on AWS yet.

  4. The partner files, AWS decides

    If the work qualifies, the partner files the funding request with AWS. AWS reviews it and decides. The amount depends on the workload.

  5. You pay nothing

    CloudRoute is free for startups. Partners pay CloudRoute a monthly membership plus 10% of AWS-approved funding.

AWS Activate credits are separate, and you apply for them yourself. Use Activate Founders if no investor backs you. Use Activate Portfolio with the Org ID or invite from your VC, accelerator, incubator or angel group if it is an Activate Provider. A consulting partner cannot apply for Activate on your behalf.

faq

Common questions

Is migrating from PostgreSQL to Aurora PostgreSQL a "real" migration, or basically a lift?
It is genuinely homogeneous — same engine, same PostgreSQL wire protocol, same SQL, same drivers, same extensions ecosystem — so there is no schema conversion and no application rewrite. In that sense it is much closer to a lift than a heterogeneous move like Oracle→Aurora. The real work is not the SQL: it is confirming extension and major-version compatibility, choosing the right data-movement method, and rehearsing a cutover with a tested rollback. Those are what a partner is for.
Will my application code and connection strings change?
Application code generally does not change at all — Aurora PostgreSQL is wire-compatible, so your ORM, drivers, and SQL work unchanged. What changes is the endpoint: you point your connection string at the Aurora cluster (writer) endpoint and, if you use replicas, the reader endpoint. Fronting that with a DNS CNAME or a centrally-managed connection string is what makes the cutover (and a rollback) a single change rather than a redeploy.
Which migration method should I use?
It comes down to where the source lives and how much downtime you can tolerate. If a maintenance window is fine: snapshot/restore (RDS source) or pg_dump/pg_restore. If the source is RDS PostgreSQL and you want near-zero downtime: create an Aurora read replica and promote it — the cleanest path. If the source is any other Postgres (self-managed, Heroku, Supabase, Cloud SQL) and you want near-zero downtime: native logical replication or AWS DMS with CDC. Most off-AWS or self-managed sources end up on DMS.
Will my extensions (pgvector, PostGIS, pg_cron, etc.) work on Aurora?
Most common extensions are supported — pgvector, PostGIS, pg_stat_statements, pg_partman, pg_cron, hstore, citext, uuid-ossp, postgres_fdw/dblink, pglogical and more — but the supported set and the exact supported version of each are tied to the Aurora PostgreSQL engine version. Inventory what you actually use (SELECT extname, extversion FROM pg_extension) and confirm each is available at a compatible version on the target. Version-sensitive extensions like pgvector deserve explicit attention because their behaviour has changed across releases.
How much downtime does the cutover actually take?
With the near-zero methods (Aurora read-replica promotion, logical replication, or DMS CDC), the data is already synced, so the only downtime is the brief quiesce-drain-promote-repoint window — typically seconds to a couple of minutes. With snapshot/restore or pg_dump/pg_restore, downtime equals the copy-and-restore time, which scales with database size (minutes for a few GB, hours for multiple TB). The number to design around is your write-downtime tolerance.
Is Aurora PostgreSQL more expensive than RDS PostgreSQL?
Per vCPU-hour and per storage-GB they are roughly comparable, with Aurora often carrying a modest compute premium that buys the distributed storage layer, faster failover, and read fan-out. The dimension to model carefully is I/O: Aurora bills storage I/O pay-per-request by default, or use Aurora I/O-Optimized to remove per-request I/O charges for I/O-heavy workloads. For spiky load, Serverless v2 can land below a provisioned instance sized for peak. Decide on a 12-month total-cost model using your real numbers, not the per-hour sticker.
Should I use Aurora Serverless v2 or provisioned instances?
Provisioned for steady, predictable load — it is the most predictable cost and usually cheapest when utilization is constant. Serverless v2 for spiky, bursty, or unpredictable workloads, and for dev/test/staging that should idle cheaply, because it scales capacity in fine-grained increments and you pay for what is consumed. A common and effective pattern is a provisioned writer for the baseline plus Serverless v2 readers to absorb bursts. Set the minimum capacity deliberately so a latency-sensitive database is not cold-scaling exactly when traffic arrives.
Can AWS fund my PostgreSQL to Aurora migration?
Only when the move is onto AWS. The AWS Migration Acceleration Program (MAP) is for workloads moving to AWS, so Postgres on Heroku, Cloud SQL, another cloud or your own servers can qualify. Your matched AWS partner files the MAP request when the migration qualifies, and AWS approves it. A move from RDS PostgreSQL to Aurora stays inside AWS and is not a MAP migration. CloudRoute is free for you either way, and you still pay for the running Aurora cluster afterwards.

Move your Postgres to Aurora with someone who has done it before

A vetted AWS partner with a PostgreSQL to Aurora track record runs the move. If your Postgres runs outside AWS today, the partner checks whether the move qualifies for MAP funding: typically $50K to $150K for startups. Depends on the workload; AWS approves. CloudRoute is free for startups.

schema conversionnone
cutover downtimesec–min
CloudRoute fee for startups$0