0%
Cloud Architecture Patterns
Cloud Foundations
Compute Patterns
Application Patterns
Infrastructure as Code
Reliability and Operations
Advanced Patterns
Managed Database Services
Running a production relational database is one of the most operationally demanding tasks in infrastructure. Patching the OS, tuning buffer pools, managing replication lag, testing backup restores at 3 AM, resizing storage without downtime: these are full-time jobs. Managed relational database services like Amazon RDS, Google Cloud SQL, and Azure Database absorb this operational burden so your team focuses on schema design, query optimization, and application logic instead of server maintenance.
The core value proposition is automation of undifferentiated heavy lifting. Backups happen on schedule without cron jobs. Minor version upgrades apply automatically during maintenance windows. Storage scales without manual volume expansion. You trade granular control for operational peace of mind.
Consider what happens when you self-host PostgreSQL. You install the OS, harden SSH access, configure the firewall, install PostgreSQL, create the data directory, tune shared_buffers and work_mem, set up pg_hba.conf for client authentication, configure WAL archiving, write a cron job for pg_basebackup, set up streaming replication to a standby, install and configure Patroni or repmgr for automatic failover, deploy Prometheus and Grafana for monitoring, and write PagerDuty alerts for disk usage, replication lag, and connection count. This takes a skilled DBA 2-3 weeks. With RDS, you click "Create Database," select PostgreSQL, check "Multi-AZ," set the backup retention to 7 days, and you have all of the above in 15 minutes.
And the work does not stop at setup. Every quarter, a new PostgreSQL minor version releases with security patches. Every year, a major version releases with new features. Self-hosted means you test the upgrade on staging, schedule the maintenance window, execute the upgrade (which may require logical replication for major versions), verify application compatibility, and roll back if anything fails. RDS applies minor versions automatically during your maintenance window and offers one-click major version upgrades with automated pre-checks.
The security patching story is particularly compelling. When a critical CVE is disclosed for PostgreSQL (like the privilege escalation vulnerabilities that appear every few years), managed services apply patches within days across all instances in your account. Self-hosted requires you to monitor vulnerability announcements, assess severity, test the patch, schedule downtime, and apply it across every instance. Organizations with 10+ self-hosted databases and no dedicated DBA team often take weeks to patch critical vulnerabilities, leaving production systems exposed.
Amazon RDS and Google Cloud SQL
Amazon RDS supports MySQL, PostgreSQL, MariaDB, Oracle, and SQL Server as engine options. Google Cloud SQL supports MySQL, PostgreSQL, and SQL Server. Both services provide the same foundational capabilities. Azure Database for PostgreSQL/MySQL provides equivalent functionality on Microsoft's cloud. The concepts are the same across all three providers; the configuration interfaces and pricing models differ, but the architecture is nearly identical.
Understanding these foundational capabilities matters because they appear in every system design discussion involving data stores. When an interviewer asks "how do you handle database reliability," these are the building blocks of your answer:
Automated backups: The service takes daily snapshots and captures transaction logs continuously. Point-in-time recovery lets you restore to any second within the retention window (up to 35 days on RDS). You never write a backup script or worry about whether last night's backup completed. The service handles storage, encryption, and cross-region replication of backup files.
Why does point-in-time recovery matter? Imagine a developer accidentally runs DELETE FROM users WHERE status = 'active' without a WHERE clause constraint, wiping production data. With point-in-time recovery, you restore to the second before the deletion, extract the missing rows, and insert them back into the live database. Without it, you restore from last night's daily backup and lose everything written since then. The ability to restore to any second turns a catastrophic data loss into a 30-minute recovery exercise.
Read replicas: A single write primary replicates to up to 5 (RDS) or 10 (Cloud SQL) read replicas. Your application directs read traffic to replicas and write traffic to the primary. This is the simplest horizontal scaling pattern for read-heavy workloads: a product catalog serving 50,000 reads per second and 500 writes per second scales by adding replicas, not by sharding.
The key architectural detail: read replicas use asynchronous replication. The primary does not wait for replicas to confirm before acknowledging the write to the application. This means replicas may be a few hundred milliseconds behind the primary (replica lag). For most read workloads, this is acceptable. A user who just posted a comment might not see it on a replica for 200ms, but every other user sees it within that window. For reads that must see the latest write (e.g., checking inventory before purchase), route those to the primary.
Connection routing: RDS provides two endpoints: a writer endpoint (always points to the primary) and a reader endpoint (load-balances across all read replicas). Your application's data access layer uses the writer endpoint for INSERT, UPDATE, DELETE statements and the reader endpoint for SELECT statements. ORM frameworks like SQLAlchemy, Hibernate, and Prisma support dual-endpoint configuration natively. The reader endpoint uses round-robin DNS to distribute connections across replicas, so adding a new replica automatically increases read capacity without changing application configuration.
Cross-region read replicas: For applications with global users, you can create read replicas in other AWS regions. A US-based primary with read replicas in Europe and Asia means European users read product data from a replica 20ms away instead of crossing the Atlantic at 100ms+. Cross-region replicas have higher lag (typically 1-5 seconds due to network latency between regions) but serve the majority of read traffic locally. This pattern is simpler and cheaper than a globally distributed database for read-heavy workloads where writes originate from one region.
Multi-AZ failover: The service maintains a synchronous standby replica in a different availability zone. If the primary instance fails (hardware failure, AZ outage, or during a maintenance event), the service promotes the standby and updates the DNS endpoint. Your application reconnects within 60-120 seconds with zero data loss because the standby is synchronously replicated. You do not write failover scripts, monitor replication lag, or test promotion runbooks. The service does all of it.
The failover sequence works like this: the service detects the primary is unhealthy (via heartbeat failure), promotes the standby to primary (which already has all committed data via synchronous replication), updates the DNS CNAME to point to the new primary's IP, and flushes the DNS TTL. Your application's connection string uses the DNS endpoint, so it automatically connects to the new primary after DNS propagates. The old primary, if it recovers, becomes the new standby. During the failover window, write operations fail with connection errors. Your application should implement retry logic with exponential backoff to handle this gracefully. Read-only operations can continue on any existing read replicas during the failover.
In interviews, multi-AZ failover is the reason you choose a managed database for any production workload. Building equivalent automated failover yourself requires consensus protocols, health checking, DNS updates, and connection draining. That is months of engineering for something RDS gives you with a checkbox.
Aurora and AlloyDB: Cloud-Optimized Engines
Amazon Aurora (MySQL/PostgreSQL compatible) and Google AlloyDB (PostgreSQL compatible) go beyond wrapping an existing database engine in managed infrastructure. They redesign the storage layer to exploit cloud architecture.
Aurora separates storage from compute entirely. The storage layer is a distributed, fault-tolerant system that replicates every write 6 ways across 3 availability zones (2 copies per AZ). Write operations are acknowledged after 4 of 6 copies confirm (quorum write). Reads require 3 of 6 copies (quorum read). This design means Aurora tolerates losing an entire AZ (2 copies gone, leaving 4 copies across 2 AZs, which still meets the write quorum of 4). It can even lose one additional copy beyond a full AZ outage (3 copies remaining, which still meets the read quorum of 3, allowing reads to continue while writes pause until a copy recovers). The storage layer self-heals by automatically re-replicating data to new storage nodes, restoring full 6-copy redundancy without operator intervention.
The compute layer (query processing, caching, transaction management) runs on separate instances that attach to this shared storage. Read replicas share the same storage volume as the primary. They do not need to replay write-ahead logs to catch up. Replica lag drops from seconds (standard MySQL replication) to single-digit milliseconds. Adding a read replica takes minutes because there is no data copy involved.
This separation of storage and compute has another powerful consequence: storage grows and shrinks automatically. Aurora storage starts at 10 GB and grows in 10 GB increments up to 128 TB as you write more data. You never provision storage, monitor disk utilization, or resize volumes. When you delete data, storage reclaims automatically. Contrast this with standard RDS where you allocate a fixed EBS volume size upfront and must manually increase it when approaching capacity, a task that can cause a brief I/O pause on older volume types.
AlloyDB takes a similar approach with a disaggregated storage architecture, adding a columnar engine that accelerates analytical queries without requiring a separate data warehouse. Both engines deliver 3-5x the throughput of standard PostgreSQL or MySQL on the same hardware, because the storage layer handles replication and durability while the compute layer focuses purely on query execution.
Aurora Serverless
Aurora also offers a serverless option that scales compute capacity automatically based on demand. Aurora Serverless v2 adjusts capacity in increments of 0.5 Aurora Capacity Units (ACUs), scaling from a minimum to a maximum you define. When traffic drops to zero, Aurora Serverless can pause the compute layer entirely (you still pay for storage). When a request arrives, it resumes within seconds.
This is particularly useful for development environments, staging databases, and infrequently accessed applications where paying for a continuously running instance wastes money. A development database that sees traffic 8 hours a day costs roughly one-third of an always-on instance. The trade-off is cold-start latency: the first request after a pause takes 5-25 seconds as Aurora provisions compute. For production workloads with steady traffic, provisioned Aurora instances are more predictable and cost-effective.
Aurora Serverless v2 improved significantly over v1. Version 1 had scaling latency of 30+ seconds and could not scale while queries were in-flight. Version 2 scales in milliseconds, can scale during active transactions, and supports read replicas, Global Database, and Multi-AZ. For production workloads with variable but non-zero traffic (e.g., a SaaS application with business-hours traffic), Aurora Serverless v2 can reduce costs by 40-60% compared to provisioned instances sized for peak, because it scales down during off-peak hours automatically.
The cost is higher than standard RDS or Cloud SQL instances, but the performance-per-dollar ratio is better for workloads exceeding 10,000 transactions per second. Below that threshold, standard managed databases are more cost-effective.