Skip to main content
Multi-Cloud · lesson 6 of 8
Multi-Cloud advanced Lesson 6 of 8

Managed Databases: Picking One Across Clouds

RDS vs Azure Database for PostgreSQL vs Cloud SQL — real failover times, backup/restore mechanics, and pricing compared at an equivalent instance size.

By SkillByExample · Published

cloud aws azure gcp databases postgresql

Same engine — PostgreSQL — on three managed services: Amazon RDS for PostgreSQL, Azure Database for PostgreSQL (Flexible Server), and Cloud SQL for PostgreSQL. Comparing the same engine everywhere is what makes this a fair comparison instead of a features list — the SQL is identical; what differs is the operational layer wrapped around it.

Provisioning an equivalent instance

4 vCPU / 16 GB RAM, single-zone (no HA yet), 100 GB storage, on each:

aws rds create-db-instance \
  --db-instance-identifier orders-db \
  --engine postgres --engine-version 16.4 \
  --db-instance-class db.m6g.xlarge \
  --allocated-storage 100 \
  --master-username admin --master-user-password '********'
az postgres flexible-server create \
  --resource-group learn-rg --name orders-db \
  --location eastus --version 16 \
  --sku-name Standard_D4ds_v5 --tier GeneralPurpose \
  --storage-size 100 --admin-user admin --admin-password '********'
gcloud sql instances create orders-db \
  --database-version=POSTGRES_16 \
  --cpu=4 --memory=16GB \
  --storage-size=100 --storage-type=SSD \
  --region=us-central1
CloudInstance classOn-demand (approx, single-AZ)
RDS for PostgreSQLdb.m6g.xlarge (4 vCPU, 16 GB)~$0.307 / hr
Azure Database for PostgreSQLStandard_D4ds_v5 (4 vCPU, 16 GB)~$0.300 / hr
Cloud SQL for PostgreSQLcustom 4 vCPU / 16 GB~$0.295 / hr

List prices, single region, single-AZ — a real quote will differ by region and changes over time, but the spread between the three (under 5%) has held for years and is worth trusting more than any single number in this table.

Failover behavior

All three use the same underlying technique — a synchronously replicated standby, promoted on failure, with the client-facing endpoint repointed rather than the client needing to know a new address.

aws rds failover-db-cluster --db-cluster-identifier orders-db-cluster
$ aws rds describe-events --source-identifier orders-db --source-type db-instance --duration 5
{
    "Events": [
        {"Message": "Multi-AZ instance failover started", "Date": "2026-09-13T10:12:01Z"},
        {"Message": "Multi-AZ instance failover completed", "Date": "2026-09-13T10:12:47Z"}
    ]
}

RDS Multi-AZ failover here: 46 seconds. RDS keeps the same endpoint DNS name and flips the CNAME target during failover — the application reconnects to the same hostname and gets the new primary once DNS propagates (usually within the client’s connection retry window).

Azure’s zone-redundant HA and Cloud SQL’s regional HA follow the same shape: a synchronous standby in a second zone, promoted on health-check failure, with the connection string unchanged. Published targets put Azure Flexible Server HA failover in the tens-of-seconds range and Cloud SQL HA typically under a minute — in the same order of magnitude as RDS, with the actual number depending more on what triggered the failover (a planned test vs. a real zone outage) than on which cloud it is. Benchmark your own failover with a real client connection before trusting any vendor’s published average; run-to-run variance is usually larger than the gap between clouds.

Backup and restore

aws rds describe-db-instances --db-instance-identifier orders-db \
  --query "DBInstances[0].{Retention:BackupRetentionPeriod,Window:PreferredBackupWindow}"
$ aws rds describe-db-instances --db-instance-identifier orders-db --query "DBInstances[0].{Retention:BackupRetentionPeriod,Window:PreferredBackupWindow}"
{
    "Retention": 7,
    "Window": "07:00-07:30"
}
aws rds restore-db-instance-to-point-in-time \
  --source-db-instance-identifier orders-db \
  --target-db-instance-identifier orders-db-restored \
  --restore-time 2026-09-13T09:45:00Z

RDS restores to a new instance, never in place — this is true of Azure and GCP too, and is the detail that catches teams off guard during an actual incident: “restore the database” means “stand up a second instance and cut traffic to it,” not “roll this one back,” on all three clouds.

RDSAzure Flexible ServerCloud SQL
Automated backup granularityContinuous (transaction logs)Continuous (WAL)Continuous (WAL)
PITR restore targetNew instanceNew serverNew instance
Default retention7 days (configurable to 35)7 days (configurable to 35)7 days (configurable to 365)
Manual/on-demand snapshotsYes, retained indefinitelyYes, retained indefinitelyYes, retained indefinitely

Cloud SQL’s 365-day ceiling on automated retention is the one real spread in this table — useful if a compliance requirement forces long PITR windows without a manual snapshot-management process on top.

Practice

1. Query the current retention window on each provisioned instance and change it to 14 days.
aws rds modify-db-instance --db-instance-identifier orders-db --backup-retention-period 14 --apply-immediately

az postgres flexible-server parameter set --resource-group learn-rg --server-name orders-db --name backup_retention_days --value 14

gcloud sql instances patch orders-db --backup-start-time=03:00 --retained-backups-count=14

Three different flag names for the same setting — --backup-retention-period, a server parameter, and --retained-backups-count — worth noting before assuming Terraform provider arguments will look alike either.

2. Enable HA (multi-zone) on each instance after the fact, without recreating it.
aws rds modify-db-instance --db-instance-identifier orders-db --multi-az --apply-immediately

az postgres flexible-server update --resource-group learn-rg --name orders-db --high-availability ZoneRedundant

gcloud sql instances patch orders-db --availability-type=REGIONAL

All three can add HA without downtime scheduling flexibility varying — RDS and Cloud SQL apply this at the next maintenance window unless forced immediately; Azure applies it online in most configurations. Check the specific provider’s current behavior before assuming “no downtime” applies unconditionally.

3. Restore each instance to a point 30 minutes in the past and note what changes about the connection endpoint.

All three produce a new instance with a new endpoint hostname — orders-db-restored, not orders-db. The application’s connection string has to change (or a proxy/DNS layer in front of it has to be repointed), which is the step most runbooks forget to script until the first real incident.

4. Compare provisioned IOPS pricing for the same 100 GB volume at 3000 IOPS on all three clouds.
aws rds describe-db-instances --db-instance-identifier orders-db --query "DBInstances[0].StorageType"

RDS bills provisioned IOPS separately from storage GB once you exceed the baseline included with gp3/io1; Azure’s Flexible Server bundles a baseline IOPS-per-GB ratio into its storage tier with a paid upgrade path; Cloud SQL ties IOPS to disk size on SSD persistent disks with a separate provisioned-IOPS SKU for higher throughput. This is the line item most likely to make three “equivalent” instances diverge in a real invoice.

Next: an actual monthly cost — not a features comparison — for 1M invocations on Lambda, Azure Functions, and Cloud Run.

Frequently Asked Questions

Why compare RDS, Azure Database for PostgreSQL, and Cloud SQL instead of Azure SQL Database?
Engine parity. RDS supports PostgreSQL, MySQL, and several others; Cloud SQL supports the same short list; Azure SQL Database is SQL Server-specific, with no matching engine on AWS or GCP. Comparing all three managed-PostgreSQL offerings keeps the underlying database identical and isolates what's actually different: the managed layer around it.
Which managed database fails over fastest?
All three target roughly the same order of magnitude — tens of seconds to about two minutes for a same-region, same-config HA failover — because all three use the same underlying technique: a synchronously replicated standby that gets promoted and a DNS or network endpoint that repoints to it. The variance between runs is usually larger than the average difference between clouds; benchmark your own failover before trusting any single published number.
How long can I keep point-in-time restore backups?
RDS and Azure Database for PostgreSQL Flexible Server both cap automated backup retention at 35 days by default configuration (RDS can be extended further with manual snapshots kept indefinitely). Cloud SQL allows configuring retention up to 365 days for automated backups. All three support point-in-time restore to any second within the retention window, not just to a nightly snapshot boundary.
Is managed PostgreSQL pricing actually the same across clouds?
Close, at equivalent vCPU/RAM — within about 10% of each other for a 4 vCPU / 16 GB instance at list price, similar to the general-purpose compute convergence seen elsewhere in this track. Storage and I/O pricing (provisioned IOPS especially) is where the real spread shows up, and it scales with your actual query pattern, not the instance size alone.