On RDS and Aurora there are two managed ways off PostgreSQL 14: modify the instance to a new major version in place, or create a Blue/Green deployment with the new version on the green side and switch over. The in-place path is simple and its downtime is the whole upgrade. Blue/Green shrinks the outage to a switchover, but for a major version it runs on logical replication, which brings limits that catch teams in the middle of the change window.

This page summarizes the AWS documentation as of 21 October 2026, with links to each source. It is not a lab result; AWS changes these limits, so re-read the linked pages before you plan.

Check the upgrade target first

# RDS for PostgreSQL
aws rds describe-db-engine-versions --engine postgres --engine-version 14.20 \
  --query "DBEngineVersions[*].ValidUpgradeTarget[*].EngineVersion" --output text

# Aurora PostgreSQL
aws rds describe-db-engine-versions --engine aurora-postgresql --engine-version <current> \
  --query 'DBEngineVersions[].ValidUpgradeTarget[?IsMajorVersionUpgrade == `true`].EngineVersion' --output text

Current RDS 14 minors list 18.x as a direct target. If yours does not, a minor-version upgrade comes first; see the PG14 minor-version deadlines.

In-place: downtime is the whole upgrade

RDS and Aurora run pg_upgrade on the instance. The database is unavailable from the start of the upgrade until it completes. AWS does not publish a formula for the duration; pg_upgrade spends much of its time dumping and restoring the schema, so many tables, indexes or large objects make it longer. AWS takes snapshots before and after the upgrade when backup retention is above zero.

  • RDS read replicas in the same Region are upgraded with the primary, which can lengthen downtime. Promote or delete them first if that matters.
  • Aurora readers each have a brief outage after the writer upgrade completes.
  • Blockers are checked first and written to pg_upgrade_precheck.log: prepared transactions, reg* columns, invalid databases, logical replication slots and unsupported extensions. See pg_upgrade --check failures and fixes.
  • Statistics: AWS's guides for both services say to run ANALYZE on every database afterwards. Budget that time inside the window; here is what skipping it does.

The only way to know the duration is to restore a snapshot (or clone the Aurora cluster) and upgrade the copy. That also produces the precheck log without touching production.

Blue/Green: a short switchover, with conditions

When the green environment runs a higher major version, RDS and Aurora replicate from blue to green with PostgreSQL logical replication. At switchover, RDS runs guardrail checks, stops writes on both sides, drops connections, waits for green to catch up, renames the instances and endpoints so the application keeps the same hostname, then allows writes on green. The switchover timeout defaults to 300 seconds and can be set from 30 to 3,600; if switchover exceeds it, everything rolls back.

AWS does not give a fixed downtime for PostgreSQL. It depends on replication lag at the moment of switchover, long-running transactions and how quickly your application reconnects. AWS warns that clients caching DNS for longer than 5 seconds keep sending writes to the old blue instance, which is read-only after switchover, so those writes fail until the cache expires. Also check that the application never sets default_transaction_read_only to off in a session: RDS turns it on for green during switchover, and any writes that slip through are missing from blue if the switchover rolls back, leaving you to reconcile them by hand.

Limits that break or block a PostgreSQL Blue/Green upgrade

From the RDS and Aurora limitation pages:

SituationWhat happens
Any DDL on blue after green is created (CREATE TABLE, ALTER TABLE, a migration, a new partition)Green enters Replication degraded; delete the deployment and green databases and start again
Large objects created or modified on blueSame: replication degraded, recreate
Blue is a logical publisher or subscriber (Debezium, DMS, pglogical)Not supported; switchover guardrails check for it. Drop the slots and subscriptions, recreate after switchover
Tables without a primary keyUPDATE and DELETE on them are not permitted; add a key or set REPLICA IDENTITY FULL
pg_partman on blue; pg_cron on greenpg_partman must be disabled on blue; pg_cron must stay disabled on green
Materialized viewsRDS: not refreshed on green. Aurora: refreshing one on blue breaks replication
Unlogged tablesNot replicated (Aurora can with rds.logically_replicate_unlogged_tables = 1 set before creation)
SequencesNot replicated continuously; RDS sets them on green during switchover. Hundreds of thousands can exceed the timeout
Heavy continuous writesGreen's apply process is single-threaded and can fall behind. AWS suggests DMS for this case
GRANT / REVOKE on blueNot replicated; you get a warning and must apply them to green yourself

The DDL rule is the one that bites SaaS teams: a routine deploy that runs a migration, or pg_partman creating next month's partition, invalidates the green environment. Freeze schema changes from green creation to switchover, and create partitions far enough ahead before you start.

After switchover

  • Point-in-time recovery history does not carry over. The new production database can only be restored back to when green was created. Keep the old blue instance for your recovery window.
  • AWS DMS tasks cannot resume from the blue checkpoint; recreate them. Other CDC tools need a new slot and a plan for the gap: what happens to logical replication slots.
  • IAM roles are not copied, and anything that filters on resource ID (CloudTrail consumers, AWS Backup, Performance Insights API calls) needs the new IDs.

Run these on blue before creating the deployment

-- Tables that cannot replicate UPDATE/DELETE
SELECT c.oid::regclass AS table_name
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r' AND c.relreplident IN ('d', 'n')
  AND n.nspname NOT IN ('pg_catalog', 'information_schema')
  AND NOT EXISTS (SELECT 1 FROM pg_constraint p WHERE p.conrelid = c.oid AND p.contype = 'p');

-- Large objects, unlogged tables, materialized views
SELECT count(*) AS large_objects FROM pg_largeobject_metadata;
SELECT oid::regclass FROM pg_class WHERE relpersistence = 'u' AND relkind = 'r';
SELECT schemaname, matviewname FROM pg_matviews;

-- Existing logical slots and subscriptions
SELECT slot_name, plugin, active FROM pg_replication_slots WHERE slot_type = 'logical';
SELECT subname FROM pg_subscription;

-- Extensions that need handling
SELECT extname FROM pg_extension WHERE extname IN ('pg_partman', 'pg_cron', 'pglogical', 'pgactive', 'pgaudit');

Then, on green before switchover, run ANALYZE in each database. AWS recommends it, and it moves the statistics rebuild out of the outage. On Aurora, Query Plan Management (apg_plan_mgmt) can hold known-good plans across the version change if plan regressions are the main risk.

Which path fits

  • In-place when a maintenance window of the measured upgrade time is acceptable, or the schema changes too often to freeze.
  • Blue/Green when the outage must be short and you can freeze DDL, handle tables without keys and large objects, and rebuild CDC afterwards.
  • DMS or self-managed logical replication when write volume is too high for a single apply worker, or you need more control over cutover and fallback.

Whichever path you choose, the performance risk is the same: plans that change on the new version. Capture a baseline before you start. The full order of work is in the PostgreSQL 14 upgrade checklist.