Skip to content

RDS backup and restore: getting to recovery confidence, not recovery hope

Amazon RDS (Relational Database Service) turns on automated backups for you, but having backups is not the same as knowing you can recover. Check how far back you can restore, time a test restore, and confirm your application works against the restored copy.

If your application’s database runs on Amazon RDS (Relational Database Service), you can find out today whether a restore would actually work when you need one. Out of the box, RDS usually keeps seven days of automated backups, takes a snapshot every night, and shows everything green in the console. That proves backups exist, not that you can recover from them. Real confidence comes from three answers you can check yourself. How far back can you restore? How long does a restore take for your database at its current size? And when did someone last run one and point the application at the result? The steps below cover each one, so you find the gaps on a quiet afternoon instead of during an incident.

What’s happening

RDS gives you two backup mechanisms that behave differently, and mixing them up causes most restore-day confusion. Automated backups are a daily snapshot plus continuous transaction log capture, retained 1 to 35 days, and they are what enables point-in-time recovery (PITR) — restoring to any second inside the window, usually up to about five minutes behind the live database. Manual snapshots are one-shot copies that persist until you delete them, survive instance deletion, and are what you copy cross-region or share cross-account.

The operational fact that surprises people: a restore never repairs the existing instance. It always creates a new instance with a new endpoint, and depending on how you launch it, with the default parameter group and VPC security group rather than the ones production uses. Your application does not follow automatically — you repoint it, or you rename instances. Restore duration is also not what people expect: the new instance becomes available while data blocks are still being lazy-loaded from S3, so the database answers queries but runs slow until the working set has been pulled in. For a large database, “available” and “back to normal performance” can be hours apart. Both behaviours are documented across the RDS documentation, but almost nobody reads them until it is urgent.

What to check first

  • Retention period. BackupRetentionPeriod of 0 means automated backups are off entirely — it happens, usually from an old Terraform default.
  • LatestRestorableTime. This is your real RPO right now. If it is hours behind instead of minutes, log shipping is unhealthy.
  • Backup window vs. load. On single-AZ instances the daily snapshot briefly suspends I/O; a window sitting inside your peak hours is self-inflicted pain.
  • Where the snapshots live. All in one region and one account means a regional event or compromised credentials takes the database and its backups together.
  • The last actual restore. If nobody can name a date, assume the restore path has unknowns in it.

How to verify

# Retention, real PITR position, and backup window
aws rds describe-db-instances \
  --db-instance-identifier prod-db \
  --query 'DBInstances[0].[BackupRetentionPeriod,LatestRestorableTime,PreferredBackupWindow]'

# Most recent automated snapshot
aws rds describe-db-snapshots \
  --db-instance-identifier prod-db \
  --snapshot-type automated \
  --query 'sort_by(DBSnapshots,&SnapshotCreateTime)[-1].[DBSnapshotIdentifier,SnapshotCreateTime,Status]'

# Manual snapshots (these survive instance deletion)
aws rds describe-db-snapshots \
  --db-instance-identifier prod-db \
  --snapshot-type manual \
  --query 'DBSnapshots[].[DBSnapshotIdentifier,SnapshotCreateTime]'

In the console the same lives under RDS > Automated backups and RDS > Snapshots. For Aurora, check the cluster instead of the instance — backups are cluster-level and continuous, and the same LatestRestorableTime question applies.

The runbook

  1. Set retention on purpose. Seven days is a reasonable floor for production; 35 is the ceiling for automated backups. Anything older than 35 days must come from manual snapshots or AWS Backup — decide which and write it down.
  2. Run a PITR restore into a scratch instance. This is the core of the whole exercise:
aws rds restore-db-instance-to-point-in-time \
  --source-db-instance-identifier prod-db \
  --target-db-instance-identifier prod-db-restore-drill \
  --use-latest-restorable-time \
  --db-instance-class db.t4g.medium \
  --no-multi-az

Time it from command to application-usable, not to instance-available. Then connect a client, verify row counts on a table you know, and delete the drill instance. 3. Fix what the drill exposed. Typical findings: the restored instance came up with the default parameter group (pass --db-parameter-group-name), the wrong security group (pass --vpc-security-group-ids), or in the wrong subnet group. Bake the correct flags into a documented restore command. 4. Copy snapshots out of the blast radius. Automated snapshots cannot be shared; copy to a manual snapshot, then copy that cross-region or share it to a recovery account. For encrypted snapshots the destination needs access to the KMS key — this is the step that fails on the day you need it, so test it now. 5. Alarm on the things that rot. LatestRestorableTime falling behind, snapshot age, and storage headroom — a database that fills its storage stops accepting writes, which no backup fixes. 6. Write the decision tree. Bad deploy five minutes ago: PITR to just before the deploy. Table dropped yesterday: PITR to a scratch instance, export the table, import into production. Region down: promote the cross-region copy. The full drill sequence lives in RDS / Aurora PITR and snapshot strategy.

When this is the wrong move

PITR is for data loss, not availability. If the instance itself dies, Multi-AZ failover recovers in a minute or two without touching backups — restoring from snapshot in that scenario throws away hours for nothing; the trade-offs are laid out in Multi-AZ vs multi-region for RDS. If your RPO is effectively zero, backups are the second line and replication is the first. And if the corruption is logical and old — bad data written three weeks ago inside a 7-day window — no RDS mechanism reaches it; that is what long-retention manual snapshots or exports are for.

Common mistakes

  • Assuming a restore fixes the instance in place. It creates a new one; the cutover — endpoint change or rename — is your job and belongs in the runbook.
  • Judging restore time by instance status. “Available” arrives long before normal performance on large databases because blocks lazy-load from S3.
  • Deleting an instance without a final snapshot. Skip it and the automated backups can go with the instance (retention of deleted-instance backups depends on settings) — take the final snapshot every time.
  • Encrypted snapshot, no key access at the destination. Cross-account and cross-region copies of encrypted snapshots fail without KMS grants that must be arranged in advance.

Prevention

  • Put LatestRestorableTime lag on a dashboard next to replication lag.
  • Run the restore drill quarterly; keep the timed result next to the written RTO.
  • Keep a documented, copy-pasteable restore command with the correct parameter group, security groups, and subnet group already filled in.
  • Automate the manual-snapshot copy to a second region or account rather than relying on someone remembering.
  • Re-test the KMS path whenever keys or key policies change.

A database team with recovery confidence can say “we restore in about 40 minutes and lose at most 5 minutes of data” and prove it with a dated drill log. If nobody on your team truly owns the AWS environment end to end, that is the root of most of these problems — Stack Harbor runs AWS accounts daily under AWS Operations, and you can book an AWS review.