dissected.io
Lesson 5 of 23
Beginnerfundamentalsdatabasesrdscloud-sqlmanaged-services10 min read

Managed Databases — RDS vs Cloud SQL vs Azure SQL

You can absolutely install Postgres on an EC2 instance, configure streaming replication, set up automated backups to S3, write monitoring scripts, handle failover, and manage OS-level patching. You can also change your own brake pads. The question is whether that's the best use of your time when there's a service that does it for you. For most teams, managed databases are the right answer — not because they're technically superior, but because database operations at 3am is nobody's favorite job.

Managed Databases — Failover and Replication

AZ-1
Primary
RDS PostgreSQL
AZ-2
Standby
RDS PostgreSQL
Sync Repl.
Replicas
Read 1
Read 2

What "Managed" Buys You

Automated backups: the provider takes regular snapshots and transaction log backups, giving you point-in-time recovery (PITR) to any second within a retention window (typically 7-35 days). You don't write the cron job. You don't worry about backup storage running out.

Automated patching: minor version upgrades and security patches are applied during maintenance windows. You pick the window; the provider does the work.

Monitoring and metrics: CPU, memory, IOPS, connections, replication lag — all piped into the provider's monitoring service (CloudWatch, Cloud Monitoring, Azure Monitor) without installing agents.

Automated failover: in multi-AZ configurations, when the primary dies, the provider promotes a standby to primary, updates the DNS endpoint, and your application reconnects — often within 60-120 seconds.

What It Costs You

Less control: no superuser/root access. You can't tune every kernel parameter, install arbitrary extensions (only approved ones), or SSH into the database server. If you need pg_stat_statements on a version the provider hasn't approved, you wait.

Version lag: providers typically support major versions 6-18 months after community release. If you need the latest Postgres feature on day one, you're running it yourself.

Higher unit price: managed database instances cost 20-40% more than equivalent compute for a self-managed VM. You're paying for the operational labor.

Opaque operations: when failover happens or performance degrades, you don't have full visibility into what the provider is doing. You're debugging through their abstractions.

AWS Implementation

RDS supports Postgres, MySQL, MariaDB, Oracle, and SQL Server. Multi-AZ deploys a synchronous standby in a different AZ — writes go to the primary and are synchronously replicated before acknowledged. Read replicas are asynchronous and can be promoted to standalone instances.

Aurora is AWS's cloud-native database. It's MySQL and Postgres compatible but reimplements the storage layer. Instead of replicating entire database instances, Aurora replicates the storage volume across 6 copies in 3 AZs. This gives better failover times (typically under 30 seconds), up to 15 read replicas sharing the same storage, and Aurora Serverless which scales compute up and down (even to zero on v2).

# Create an Aurora Postgres cluster
aws rds create-db-cluster \
  --db-cluster-identifier my-cluster \
  --engine aurora-postgresql \
  --engine-version 15.4 \
  --master-username admin \
  --master-user-password $DB_PASSWORD \
  --storage-encrypted

GCP Implementation

Cloud SQL supports Postgres, MySQL, and SQL Server. HA configuration uses regional persistent disk and a standby instance in a different zone. Failover is automatic but can take 1-2 minutes including DNS propagation.

AlloyDB is Google's answer to Aurora — Postgres-compatible with a disaggregated storage architecture, claiming 4x throughput over standard Postgres. It's newer and less battle-tested but follows the same "compatible engine, reimagined storage" playbook.

Spanner is the outlier — a globally distributed, strongly consistent relational database. It's the only managed service that gives you ACID transactions across regions. The tradeoff: it's expensive, has a unique SQL dialect, and you need to design your schema around its distributed architecture. But when you need global consistency, nothing else does this.

Azure Implementation

Azure SQL Database is Microsoft's managed SQL Server offering. It's deeply integrated with the Microsoft ecosystem and offers unique features like elastic pools (multiple databases sharing a resource pool) and Hyperscale (up to 100 TB with rapid scale-out).

Cosmos DB is Azure's globally distributed, multi-model database. It offers five consistency levels (from strong to eventual), which is more nuanced than most providers. Like Spanner, it targets globally distributed workloads, but with a NoSQL (document/graph/key-value) data model rather than relational.

Azure Database for PostgreSQL and MySQL are also available for teams that want open-source engines without the SQL Server ecosystem.

Side-by-Side Comparison

AspectAWSGCPAzure
Standard managedRDS (5 engines)Cloud SQL (3 engines)Azure SQL DB, Database for PG/MySQL
Cloud-nativeAurora (MySQL/PG)AlloyDB (PG)Hyperscale
Global distributionAurora Global DatabaseSpannerCosmos DB
Serverless optionAurora Serverless v2Cloud SQL does not scale to zeroAzure SQL Serverless
Max read replicas15 (Aurora), 5 (RDS)10 (Cloud SQL)4 (Azure SQL)
Failover time~30s (Aurora), ~60s (RDS)60-120s~30s (Premium tier)
Backup retentionUp to 35 daysUp to 365 daysUp to 35 days (LTR available)

HA Topologies

The standard pattern is a synchronous standby in a different AZ. Writes are acknowledged only after both the primary and standby have the data. This gives you zero data loss (RPO=0) on failover but adds a few milliseconds of write latency.

Read replicas use asynchronous replication. They reduce read load on the primary but have replication lag — reads might be slightly stale. Cross-region read replicas give you disaster recovery and lower read latency for geographically distributed users, but lag is higher (100ms+ of network latency plus apply time).

Backups: The Rule You Must Follow

An untested restore is not a backup. Every managed database provider gives you automated backups and PITR. But if you've never actually restored from one, you don't know if your backup process works, how long it takes, or whether your application can reconnect gracefully. Schedule restore tests quarterly at minimum. Automate them if you can.

Snapshots are point-in-time copies of the entire database. They're fast to create (usually minutes) but restoration creates a new instance — you can't restore in-place. PITR uses the combination of a base snapshot plus transaction logs to restore to any specific second. It's slower but more precise.

The Connection Exhaustion Trap

Every managed database has a maximum connection limit based on instance size. A typical small Postgres instance supports 50-100 connections. Each connection consumes memory on the database server.

This becomes a problem with serverless compute (Lambda, Cloud Functions, Cloud Run). Each invocation might open a database connection. Under load, you can quickly exhaust connections. The solution: connection pooling. AWS has RDS Proxy, GCP has the Cloud SQL Auth Proxy (plus AlloyDB's built-in pooling), and Azure has connection pooling built into some tiers. Alternatively, use an external pooler like PgBouncer.

Cost Structure

Managed database costs have multiple components: instance hours (the compute), storage (GB/month), IOPS (on provisioned-IOPS volumes), backup storage (beyond the free retention), and data transfer (cross-AZ and cross-region replication, egress). A production multi-AZ Postgres setup with reasonable storage typically starts at $200-400/month and scales from there.

Key Takeaways

  • Managed databases trade control and unit cost for operational sanity — automated backups, patching, monitoring, and failover are worth the premium for most teams
  • Aurora (AWS) and AlloyDB (GCP) reimagine the storage layer for better failover and read scaling while staying Postgres/MySQL compatible
  • Spanner and Cosmos DB solve global distribution but with significant cost and complexity; you need a concrete requirement before reaching for them
  • An untested restore is not a backup — schedule quarterly restore drills or automate them
  • Connection pooling is mandatory when pairing serverless compute with managed databases; without it, you'll exhaust connections under load
  • Cost is instance + storage + IOPS + backup + egress; the instance hours are just the beginning

Next up, we'll tackle the most important and most misconfigured service in any cloud account — IAM.

Enjoyed this breakdown?

Get new lessons in your inbox.