AWS RDS and Google Cloud SQL run the engine (MySQL, PostgreSQL, SQL Server) so you skip patching and hardware — but "managed" is not "unmanaged." This guide covers the day-to-day tasks you still own.
Prerequisites
- An AWS or GCP account with permission to create a database instance.
- The CLI installed (
awsorgcloud) and configured. - Basic SQL and the earlier MySQL/PostgreSQL admin concepts.
What the cloud does vs what you do
| The cloud handles | You handle |
|---|---|
| OS + engine patching, hardware | Schema & query performance |
| Replication plumbing | Instance sizing & scaling |
| Automated backup storage | Backup/retention policy & restore tests |
| Failover mechanics | Failover testing, security, cost |
Backups and restore
- Automated backups + point-in-time recovery are on by default — set the retention window (7–35 days) to your needs. Both clouds restore to any second in that window by creating a new instance.
- Take a manual snapshot before risky changes (a big migration, a schema change); these persist until you delete them.
- Practice a restore. The first time you restore should not be during an incident.
# AWS: point-in-time restore to a new instance
aws rds restore-db-instance-to-point-in-time \
--source-db-instance-identifier prod \
--target-db-instance-identifier prod-restore \
--restore-time 2026-07-23T09:00:00Z
# GCP: clone to a point in time
gcloud sql instances clone prod prod-restore \
--point-in-time '2026-07-23T09:00:00Z'
High availability and failover
- RDS Multi-AZ / Cloud SQL HA keeps a standby in another zone and fails over automatically; your app reconnects to the same endpoint.
- Read replicas offload read traffic and can be promoted. Watch replication lag — your app must tolerate slightly stale reads on replicas.
- Test failover deliberately so you know the reconnect behavior and timing:
aws rds reboot-db-instance --db-instance-identifier prod --force-failover
gcloud sql instances failover prod
Scaling
- Vertical: change the instance class/tier — schedule it, since it briefly interrupts (Multi-AZ/HA makes it near-seamless).
- Storage: enable storage autoscaling so you don't run out at 2am. Storage usually can't shrink, so grow deliberately.
- Read scaling: add replicas rather than one giant primary.
Parameters and maintenance
- Engine settings live in parameter groups (RDS) / flags (Cloud SQL) — not on a shell. Change
max_connections, timeouts, etc. there; some need a reboot. - Set a maintenance window so patches land when traffic is low.
Choosing the instance, and connecting the right way
Two decisions you'll make repeatedly: how big an instance, and how apps connect to it.
Sizing. Managed databases are billed by instance class/tier, and the temptation is to over-provision "to be safe." Instead, size from the metrics you already have: pick the class where CPU sits comfortably below ~70% at peak and there's healthy free memory (so the working set stays cached). Memory matters more than raw CPU for most databases — a too-small instance thrashes to disk. Start moderate, watch a week of real load, then adjust; both clouds let you resize with a short (Multi-AZ/HA: near-seamless) interruption.
Connections — the #1 managed-database incident. Cloud databases have a max_connections tied to
instance size, and serverless/containerized apps love to open connections without limit. When they blow
through the cap, everything fails at once. Two defenses, use both: a connection pool in the app,
and a server-side pooler — RDS Proxy (AWS) or the Cloud SQL Auth Proxy / PgBouncer (GCP). RDS
Proxy also smooths failovers by holding connections steady while the backend swaps. If you take one
operational lesson from this article, make it pool your connections.
Connect securely, not with a public IP. Prefer IAM database authentication (short-lived tokens instead of long-lived passwords) where the engine supports it, and reach the database over a private path — the Cloud SQL Auth Proxy, PrivateLink/private endpoints, or VPC peering — rather than exposing a public IP and an allow-list you'll forget to prune.
Choosing the engine and edition
"RDS" and "Cloud SQL" aren't one thing — picking the right variant shapes cost and capability:
- Vanilla engines — RDS/Cloud SQL for PostgreSQL, MySQL, SQL Server (and MariaDB on AWS) run the real open-source engine, managed. Full compatibility, easy lift-and-shift. The default choice.
- Aurora (AWS) — Amazon's MySQL/Postgres-compatible engine with a distributed storage layer: higher throughput, up to 15 low-lag read replicas, faster failover, and storage that auto-grows. Costs more, but scales further; Aurora Serverless v2 scales capacity automatically for spiky/intermittent workloads so you don't pay for a big idle instance.
- AlloyDB (GCP) — Google's Postgres-compatible engine tuned for heavy transactional + analytical workloads, the Aurora analogue.
Rule of thumb: start with the vanilla engine for compatibility and cost; move to Aurora/AlloyDB when you need their scale, replica count, or failover speed; reach for Aurora Serverless v2 when load is spiky and you want to stop paying for idle.
Migrating in: DMS & Database Migration Service
Moving an existing database into RDS/Cloud SQL is a routine task with dedicated tooling. AWS DMS (Database Migration Service) and GCP's Database Migration Service do a full load + change data capture (CDC): they copy existing data, then stream ongoing changes so the source and target stay in sync until you're ready to cut over — enabling a near-zero-downtime migration. The playbook:
- Provision the target instance sized for the workload.
- Start a full-load + CDC migration task from the source.
- Let it catch up, then validate row counts and spot-check data.
- During a short window, stop writes to the source, let CDC drain, and repoint the app.
DMS can even convert between engines (with the Schema Conversion Tool) for a MySQL→Postgres-style move. Always rehearse the cutover on a copy first.
Monitoring: Performance Insights & Query Insights
Managed databases give you query-level observability without extra setup. RDS Performance Insights and Cloud SQL Query Insights show you which queries are consuming the most database time, broken down by wait type (CPU, I/O, locks) — the fastest way to find the one query dragging the whole instance. Combine that with the standard metrics (CloudWatch / Cloud Monitoring): CPU, freeable memory, storage headroom, connection count, read/write IOPS and latency, and replica lag. Set alarms before limits — storage at 85%, connections at 80% of max — so you act on a warning, not an outage.
Cost optimization
Managed convenience has a price; keep it in check:
- Right-size from real metrics rather than provisioning "to be safe" — the biggest single lever.
- Commit for steady workloads: RDS Reserved Instances / Cloud SQL committed-use discounts cut 30–60% off a baseline you know you'll run.
- Serverless for spiky ones: Aurora Serverless v2 / Cloud SQL's smaller tiers avoid paying for idle.
- Watch the hidden costs: cross-AZ/region traffic, storage that only grows (and its IOPS), provisioned IOPS you no longer need, and forgotten snapshots and idle instances — the classic sources of a creeping bill.
- Scale non-production down on nights/weekends, or stop dev instances entirely when unused.
Read replicas & scaling reads
Most applications read far more than they write, so the first scaling move is usually read replicas. Both RDS and Cloud SQL let you add replicas with a click; they receive changes from the primary and serve read-only queries. The pattern: send writes to the primary endpoint, and route heavy read traffic (reports, search, dashboards) to replicas. Two things to respect:
- Replication lag. Replicas are slightly behind, so don't read-your-own-write from a replica (a user who just saved won't see their change). Route read-after-write to the primary.
- Replicas aren't backups. They replicate mistakes instantly — a bad
DELETEhits replicas too. You still need real backups.
Replicas can also be promoted to a standalone primary (for failover or region moves), and Aurora/ AlloyDB extend this with many low-lag replicas and reader endpoints that load-balance automatically.
Tuning managed databases: parameters & storage
You can't edit postgresql.conf on a shell, but you have the same knobs through the cloud's controls:
- Parameter groups (RDS) / flags (Cloud SQL) hold engine settings —
max_connections,work_mem,innodb_buffer_pool_size, timeouts. Change them here; note some are static and need a reboot (pending-reboot), and apply changes in a maintenance window. - Storage type and IOPS. Pick gp3/SSD for general use; provision higher IOPS for I/O-heavy workloads, and remember storage generally only grows — enable autoscaling so you don't wake up to a full disk, and don't over-provision IOPS you no longer need.
- Right-size, then commit. Tune the instance to real metrics first; only buy reserved/committed capacity once the baseline is stable.
The managed layer changes how you tune (API/console, not files), not what matters — the same engine settings drive performance.
A safe cutover runbook
Whether migrating in or failing over, a rehearsed runbook turns a scary event into a routine one:
- Prepare — provision and size the target; replicate data (DMS/DMS + CDC or a read replica) until it's caught up.
- Validate — compare row counts, spot-check critical tables, run the app against the target in a staging pass.
- Freeze & drain — during a short window, stop writes to the source and let replication drain to zero lag.
- Cut over — repoint the app (ideally via a DNS/endpoint change or a connection string in a secret, so it's one switch), and verify health.
- Watch & keep a rollback — monitor errors and latency; keep the old database intact until you're confident, so rollback is just repointing back.
Rehearse it on a copy first. The teams that migrate calmly are the ones who practiced the cutover before doing it for real.
Multi-region & disaster recovery
Multi-AZ/HA protects you from a zone failure; a region failure (or an accidental data corruption that replicates everywhere) needs a broader plan. Know the levers and their trade-offs:
- Cross-region read replicas keep a warm copy in another region. In a regional disaster you promote it to primary. Cheap insurance, with some replication lag as your worst-case data loss (RPO).
- Cross-region automated backups / snapshot copies give you a restore point in a second region even if the primary region is unreachable — slower recovery (RTO), but protects the backups themselves.
- Aurora Global Database / AlloyDB cross-region offer fast cross-region replication and quick promotion for demanding RTO/RPO targets.
The key discipline is to define your RPO and RTO first — how much data can you lose, and how long can you be down — then pick the cheapest option that meets them, and rehearse the failover. A DR plan you've never tested is a guess. For most applications, cross-region backups plus a documented, practiced restore procedure is enough; only latency- or availability-critical systems need the always-on global options.
Security and cost — the two that bite
- Keep databases in private subnets, reachable only from your app's security group/VPC — never publicly exposed. Use IAM database auth where available and rotate credentials with Secrets Manager / Secret Manager.
- Watch cost: right-size idle instances, buy reserved/committed pricing for steady workloads, and delete forgotten manual snapshots and old instances.
Verify it worked
- The restore/clone creates a new instance you can connect to and query — same data, new endpoint.
- After a forced failover, your app reconnects within the expected window (measure it).
- Monitoring shows connections, CPU, free storage, and replica lag trending normally.
Troubleshooting
- Can't connect → security group / authorized networks, or the DB is in a private subnet with no route from your client. Check the network path first, credentials second.
- Storage full, instance stuck → enable autoscaling; free space by pruning logs/old data. Storage can't shrink.
- A parameter change "didn't apply" → it's
pending-reboot; some parameters need a restart. - Read replica serving stale data → replication lag under load; check the lag metric and don't route read-after-write queries to replicas.
- Surprise bill → an oversized instance, cross-AZ/egress traffic, or forgotten snapshots. Right-size and clean up.
Where to go next
Our free course runs the real console + CLI tasks on RDS and Cloud SQL: restore to a point in time, trigger a failover, add and promote a replica, and change a parameter — the muscle memory of managed database operations, in a guided lab.