Running Postgres or MySQL yourself on an EC2 instance means you're also responsible for patching, backups, failover, and replication — all real, ongoing operational work most teams would rather not own. RDS trades a meaningful amount of control for someone else handling all of that correctly.
4 min read
RDS (Relational Database Service) runs a managed instance of a relational database engine (PostgreSQL, MySQL, MariaDB, SQL Server, Oracle) — AWS handles the underlying OS, database software installation and patching, automated backups, and (if configured) failover, while you interact with it as a normal database over a connection string, same as any self-hosted instance.
resource "aws_db_instance" "main" {
identifier = "app-db"
engine = "postgres"
engine_version = "16.3"
instance_class = "db.t3.micro"
allocated_storage = 20
storage_type = "gp3"
db_name = "myapp"
username = "appuser"
password = var.db_password # from a secret, never hardcoded — see the Cloud
# Computing domain's secrets-management lesson
vpc_security_group_ids = [aws_security_group.db.id]
db_subnet_group_name = aws_db_subnet_group.main.name
backup_retention_period = 7
multi_az = false # true for production — covered below
skip_final_snapshot = false
}This single resource replaces what would otherwise be: provisioning a server, installing PostgreSQL, configuring it, setting up a backup cron job, and building your own failover process — RDS does all of that as part of the managed service.
Setting multi_az = true provisions a synchronous standby replica in a different availability zone. Every write to the primary is synchronously replicated to the standby before being acknowledged, and if the primary instance or its entire AZ fails, RDS automatically fails over to the standby — typically within a minute or two, with the same endpoint address (DNS simply repoints), so application code doesn't need to know a failover happened.
This directly applies the availability-zone concept from the Cloud Computing domain's regions/AZs lesson — Multi-AZ RDS is what "spread across AZs for fault tolerance" looks like specifically for a managed database, and it's the standard production setting; multi_az = false (a single instance, no standby) is appropriate for dev/staging, not production.
Read replicas are asynchronously-replicated copies of the primary that can serve read-only queries, scaling read capacity horizontally by directing read-heavy traffic (reporting, analytics, read-only API endpoints) away from the primary.
resource "aws_db_instance" "read_replica" {
identifier = "app-db-replica"
replicate_source_db = aws_db_instance.main.identifier
instance_class = "db.t3.micro"
}The critical distinction from Multi-AZ: read replica replication is asynchronous, meaning a replica can lag slightly behind the primary — reading from a replica is not guaranteed to reflect the very latest write. Multi-AZ standbys are for failover (synchronous, not queryable directly, invisible during normal operation); read replicas are for read scaling (asynchronous, actively queryable, visibly separate). A common design mistake is trying to use a read replica for something that needs strict read-after-write consistency (e.g., reading a record immediately after creating it) — the replica might not have caught up yet.
A DB parameter group holds engine-configuration settings (connection limits, query timeouts, logging verbosity) that would otherwise require editing a config file directly on a self-managed database — since RDS doesn't give direct OS/file access, parameter groups are the managed equivalent.
resource "aws_db_parameter_group" "main" {
family = "postgres16"
parameter {
name = "log_min_duration_statement"
value = "1000" # log any query slower than 1000ms
}
}A real, common gotcha here: some parameters apply immediately, others require a database restart, and a few require replacing the instance entirely — checking a parameter's apply_method before assuming a change takes effect live is worth doing before relying on it during a live incident.
RDS takes automated backups daily within a configured retention window (up to 35 days), enabling point-in-time restore to any second within that window. Manual snapshots are user-triggered, kept until explicitly deleted (not subject to the retention window), and are the right tool before a risky schema migration or major version upgrade — a manual snapshot immediately before a dangerous change is cheap insurance against needing to explain why the automated backup from six hours ago is the best available recovery point.
Check your understanding
A quick comprehension check — not tracked, not graded, just for you.
1. What does RDS Multi-AZ actually provide?
2. What is the key difference between a Multi-AZ standby and a read replica?
3. When should a manual RDS snapshot be taken instead of relying solely on automated backups?
4. What is a DB parameter group used for?
AWS