Skip to content
ExponaBLOG
AWS FOR DEVELOPERS · DAY 041 / 100

RDS backups and point-in-time recovery, explained simply

Know how to restore before you need to.

Expona Admin7 min read

I've been woken up at 3 AM more than once because a production database got corrupted or someone ran the wrong migration. The difference between a sleepless night and a quick recovery? Understanding RDS backups and point-in-time recovery. After 5+ years managing databases at scale, I can tell you that knowing how to restore before you need to is the single best insurance policy for your data.

Automated backups with retention up to 35 days

RDS handles backups automatically for you, and this is one of those AWS features that just works in the background until you desperately need it. By default, RDS takes daily snapshots and keeps transaction logs, giving you continuous backup coverage with zero configuration required.

Here's what actually happens: every day during your backup window (which you can customize, defaulting to a random 30-minute slot), RDS creates a snapshot of your entire database. Separately, it continuously backs up transaction logs in 5-minute intervals. This dual approach means you're not just getting once-per-day recovery points—you can restore to any specific second within your retention period.

The retention period defaults to 7 days but can be extended up to 35 days. I typically set this to 14 or 21 days for production systems because one week isn't enough time to catch all possible issues. A bad data load might not surface immediately in application tests; you might discover it after 8 days of subtle data inconsistency.

To adjust retention programmatically:

bash
aws rds modify-db-instance \
  --db-instance-identifier my-production-db \
  --backup-retention-period 21 \
  --apply-immediately

Keep in mind that longer retention periods cost more in storage. On a busy OLTP database, 35 days of logs can add up. I've seen bills jump by $200-400 per month per database instance when retention goes from 7 to 35 days, so make the decision based on your compliance requirements and risk tolerance, not just defaults.

Also critical: automated backups only exist while the instance exists. Delete your DB instance and those backups are gone (unless you explicitly create a final snapshot during deletion). I've seen junior developers spin up test databases and forget to delete them for months, then panic when they need to clean up.

Point-in-time restore creates a new instance

This is where the magic happens. When something goes wrong, you can restore your database to any second within the retention period by performing a point-in-time restore (PITR). The critical thing to understand: PITR doesn't overwrite your current database. It creates a brand new RDS instance with the restored data.

Let me walk through a real scenario I handled. We had a trading platform where a batch job incorrectly updated buy prices for 50,000 items at 14:32:15 UTC. We discovered it at 14:47 UTC (the application received customer complaints). Rather than scrambling to reverse 50,000 updates, I simply restored to 14:30 UTC, verified the data was correct, and had operations switch traffic over to the restored instance. The whole process took 12 minutes for a 400GB database.

Here's how to initiate a point-in-time restore via AWS CLI:

bash
aws rds restore-db-instance-to-point-in-time \
  --source-db-instance-identifier my-production-db \
  --target-db-instance-identifier my-production-db-restored \
  --restore-time 2024-01-15T14:30:00Z \
  --db-instance-class db.r6i.2xlarge \
  --db-subnet-group-name my-subnet-group

Important parameters here: source-db-instance-identifier tells AWS which database to restore from. target-db-instance-identifier is your new instance name—it must be unique. restore-time is ISO 8601 format and must be within your retention period. db-instance-class doesn't have to match the source; I often restore to a smaller instance for testing, then to a larger one if promoting back to production.

The restore process typically takes 5-15 minutes depending on database size, but that time is spent building the new instance from backups and replaying transaction logs. During this time, your original database is untouched and serving traffic normally. Once the restore completes, you have several options: validate the data, run analytics, or promote it as your new production instance by updating application connection strings.

A mistake I see often: developers restore to point-in-time but forget to change parameter groups or security groups. The restored instance gets default security group rules, so your application might not even be able to connect. Always script your restore workflows to include all networking configuration.

Manual snapshots for releases

Beyond automatic backups, you should manually create snapshots before deployments, schema migrations, or any risky operations. Manual snapshots are independent of the retention period—they persist until you explicitly delete them, making them perfect for release gates and compliance requirements.

I always take a manual snapshot before any deployment to production. Not because I expect something to go wrong (we have test environments for that), but because it takes 10 seconds and gives me a known good state to revert to if an unforeseen issue emerges post-deployment.

Creating a manual snapshot:

bash
aws rds create-db-snapshot \
  --db-instance-identifier my-production-db \
  --db-snapshot-identifier my-production-db-pre-deployment-v2-5-3 \
  --tags Key=Environment,Value=production Key=Release,Value=v2.5.3

Notice the naming convention: including the release version makes it obvious which snapshot corresponds to which deployment. Always tag your manual snapshots too—when you have 50 snapshots, names and tags become your best friend for finding the right one under pressure.

I recommend keeping manual snapshots for at least the last 3-5 releases. With typical RDS snapshot storage costs around $0.023 per GB-month, even 10 snapshots of a 500GB database is only about $115/month—insurance well worth the cost.

One workflow I use for larger teams: automate snapshot creation using EventBridge + Lambda during deployment pipelines. This removes the human element and ensures every production deployment has a snapshot.

bash
aws events put-rule \
  --name "rds-pre-deployment-snapshot" \
  --event-pattern '{"source":["custom.deployment"],"detail-type":["DeploymentStarted"]}'

Practice restores regularly

This is non-negotiable. The worst time to learn whether your restore process actually works is when your database is down and customers are losing money. I've seen teams discover during an actual disaster that their backup files are corrupted, or that nobody documented how to restore, or that the restored instance doesn't have the right encryption keys.

I recommend quarterly restore drills for any production database. Pick a random point-in-time within the last week, restore to a new instance, and actually run queries to verify the data looks correct. Run your application's integration tests against it. This takes 30 minutes and catches issues before they matter.

Here's a simple bash script I use for backup validation:

bash
#!/bin/bash
set -e

# Configuration
SOURCE_DB="my-production-db"
RESTORE_TIME="2024-01-15T10:30:00Z"
TARGET_DB="backup-validation-$(date +%s)"
INSTANCE_CLASS="db.t3.medium"
SUBNET_GROUP="my-subnet-group"

echo "Starting point-in-time restore to $TARGET_DB at $RESTORE_TIME..."

aws rds restore-db-instance-to-point-in-time \
  --source-db-instance-identifier "$SOURCE_DB" \
  --target-db-instance-identifier "$TARGET_DB" \
  --restore-time "$RESTORE_TIME" \
  --db-instance-class "$INSTANCE_CLASS" \
  --db-subnet-group-name "$SUBNET_GROUP"

echo "Waiting for instance to be available (this takes 5-15 minutes)..."
aws rds wait db-instance-available --db-instance-identifier "$TARGET_DB"

echo "Restore complete. Run your validation queries against this instance."
echo "After validation, delete it with:"
echo "aws rds delete-db-instance --db-instance-identifier $TARGET_DB --skip-final-snapshot"

Beyond just technical validation, these drills also help your team understand the restore process. When an actual incident happens at 2 AM, whoever's on call will have done this before and won't be discovering the process from documentation they've never read.

Common mistakes

  • Forgetting the backup retention period defaults to 7 days. You might assume you have 35 days of backups automatically; you don't. Check your actual retention setting and adjust it based on your incident response SLA and compliance requirements.
  • Restoring to the same instance name. RDS won't let you, but the resulting error message is confusing. Always use a new instance identifier with a clear naming scheme indicating it's a restore.
  • Not testing restore procedures until disaster strikes. Practice restores in staging or lower environments regularly. The first time you do this should not be during an active incident.
  • Assuming restored instances inherit all properties. Parameter groups, security groups, option groups, encryption keys—you need to explicitly configure these on the restored instance. Automate this with CloudFormation or Terraform.
  • Deleting the source database during a restore. The restore process references the source, so keep it alive until the restore completes and you've validated the data.
  • Ignoring snapshot storage costs. Manual snapshots accumulate quickly. Every database I manage has a lifecycle policy that automatically deletes snapshots older than 90 days, except for tagged release snapshots.

Key takeaways

  • Automated backups with configurable retention (up to 35 days) are enabled by default, but adjust retention based on your risk tolerance and incident response window, not defaults.
  • Point-in-time restore creates a new database instance with data from any second within the retention period—it doesn't modify your current instance.
  • Take manual snapshots before releases, deployments, and risky operations; they persist indefinitely and cost far less than emergency recovery efforts.
  • Practice restore procedures quarterly in lower environments to catch issues before they become production incidents.
  • Automation is your friend—script snapshot creation during deployments and use EventBridge or Lambda to remove manual steps that humans forget under pressure.
ShareXLinkedInReddit

Found this useful? Support the writing.

Buy me a coffee
Written by
Expona Admin
Site administrator

Comments

Loading comments…

Leave a comment

Comments are reviewed before they appear. Be kind and stay on topic.

Related articles