RDS automated backups: the basics
Why a retention period of 0 is a silent recovery gap
Amazon RDS has a built-in safety net called automated backups. When it's on, RDS takes a full daily snapshot during a configured backup window and continuously streams the database's transaction logs to S3-backed storage. Together those two things let you restore the database to any single second within the retention window — that's point-in-time recovery (PITR). The retention window is controlled by one setting, BackupRetentionPeriod, which can be anywhere from 1 to 35 days.
Setting BackupRetentionPeriod to 0 turns the entire mechanism off. No daily snapshot, no transaction-log capture, and — the part people miss — no point-in-time recovery at all. The check flags any RDS DB instance running with a retention period of 0. It's almost always an accident: a value left at zero in a Terraform module, a copy-pasted launch config, or a deliberate choice for a throwaway database that quietly graduated into something production depends on.
It's flagged because the failure mode is invisible until the worst possible moment. The database runs fine for months. Then a bad migration, a DELETE without a WHERE, a corrupted write, or a fat-fingered deploy mangles the data — and there is nothing to roll back to. With backups off, recovery isn't slow; it's impossible. The protection costs almost nothing, which makes leaving it off one of the cheapest mistakes to fix and most expensive to discover.
In this lesson you'll learn how RDS automated backups actually work — the daily snapshot plus continuous transaction-log capture that together enable point-in-time recovery to any second in the window — and why a retention period of 0 silently removes that capability. You'll see how to inventory which instances have backups disabled, the exact AWS CLI flag to enable them, what the change does to a running instance (no downtime, with a one-time backup), why the backup window has negligible performance impact (especially on Multi-AZ, where the backup runs against the standby), the 1–35 day retention range and what drives the choice, the near-zero cost (free up to the DB's allocated size), and how this differs from a centralized AWS Backup plan.
The 30-second rewind that saved a Friday deploy
A growth-stage SaaS team shipped a migration on a Friday afternoon that accidentally ran an UPDATE against the wrong table, blanking a column on two million customer rows. Panic — until someone remembered the production database had a 14-day backup retention. They spun up a point-in-time restore to the second just before the migration ran, copied the good column back, and were whole again inside an hour. The total backup storage bill that had bought them that escape hatch: $0 — the database was smaller than its own allocated storage, so the backups were entirely within the free tier. A sibling service that had been launched with retention set to 0 wasn't so lucky six months later.
Enabling RDS backups in action
Priya runs the reliability cadence at a mid-sized fintech. The dashboard flags payments-ledger-db, a db.r6g.large Postgres instance, with BackupRetentionPeriod: 0 — automated backups completely off. It's been that way since launch; the Terraform module it was created from had the retention default left at zero and nobody noticed. This is the database behind settlement, so a corrupting write with no recovery path would be a reportable incident.
She confirms the scope first: describe-db-instances shows BackupRetentionPeriod: 0 and a Multi-AZ deployment, which means enabling backups will take the daily snapshot from the standby with zero impact on the primary. She picks a 7-day retention to start (the team's standard for transactional data) and a 03:00-04:00 UTC backup window that sits in the service's quiet hours.
Priya runs modify-db-instance with --backup-retention-period 7, the window, and --apply-immediately. RDS takes one immediate full backup and begins streaming transaction logs; the instance stays online and serving the whole time. A few minutes later the change settles, point-in-time recovery is live to any second in the trailing week, and the next scan flips the finding to resolved. The ledger went from zero recovery options to a 7-day rewind window — at no measurable cost, because the backup storage fits inside the database's free allocation.
First, find every RDS DB instance with automated backups disabled — these are the instances running with no point-in-time recovery.
Retention-zero inventory; cross-reference each Id against its data class before deciding which must be enabled.
For a data-bearing instance, enable automated backups with a sensible retention window and an off-peak backup window. The instance stays online throughout.
The --backup-retention-period flag turns backups on; the first enable triggers a one-time backup but no downtime.
RDS automated backups under the hooddeep dive
An automated backup is two cooperating mechanisms. Once a day, during the PreferredBackupWindow, RDS takes a storage-level snapshot of the volume — incremental after the first, so only changed blocks are copied. Separately and continuously, RDS uploads the database's write-ahead/transaction logs to Amazon S3 every few minutes. To restore to a specific moment, RDS provisions a new instance from the most recent daily snapshot before that moment and then replays the transaction logs forward to the exact second you asked for. That replay is what makes point-in-time recovery possible, and it's why setting BackupRetentionPeriod to 0 — which stops the log capture — removes PITR entirely, not just the daily snapshot.
The performance cost of the backup window is small and bounded. On a single-AZ instance there can be a brief I/O suspension at the instant the daily snapshot is initiated; on a Multi-AZ instance RDS takes the snapshot from the standby, so the primary sees no impact at all. Continuous log shipping runs in the background and is negligible. This is why the standard advice is to set a backup window in off-peak hours rather than to avoid backups — the protection is effectively free of both dollars and performance.
On cost: AWS provides backup storage free of charge up to the total allocated storage of the source database. Only backup storage that exceeds the database's allocated size is billed, at roughly $0.095 per GB-month in US-East-1. So a 200 GB database with 7-day retention whose backups stay under 200 GB pays nothing; retention only starts costing money once the accumulated snapshots plus logs exceed the live database size. Note that automated backups are deleted when the instance is deleted (unless you take a final manual snapshot) and are distinct from — and complementary to — a centralized AWS Backup plan, which manages cross-service, cross-account, and longer-term retention policies on top of the per-instance setting.
# Inspect a single instance's backup posture and the window it uses.
aws rds describe-db-instances \
--db-instance-identifier payments-ledger-db \
--query 'DBInstances[0].{Retention:BackupRetentionPeriod,Window:PreferredBackupWindow,MultiAZ:MultiAZ,LatestRestorable:LatestRestorableTime}' \
--output json
# Enable backups during the next maintenance window instead of immediately.
aws rds modify-db-instance \
--db-instance-identifier payments-ledger-db \
--backup-retention-period 7 \
--preferred-backup-window 03:00-04:00 \
--no-apply-immediately
# After enabling, confirm point-in-time recovery is live: LatestRestorableTime
# advances continuously once transaction-log capture is running.
aws rds describe-db-instances \
--db-instance-identifier payments-ledger-db \
--query 'DBInstances[0].[BackupRetentionPeriod,LatestRestorableTime]' \
--output text What is the impact of disabled RDS backups?
The headline impact is unrecoverable data loss. With BackupRetentionPeriod at 0 there is no daily snapshot and no transaction-log capture, so there is nothing to restore from. A bad migration, an application bug that corrupts rows, a DELETE or UPDATE run against production by mistake, or storage-level corruption all become terminal events: the data is simply gone. This is categorically different from a slow recovery — it's the absence of any recovery path, and it's invisible right up until the moment you need it.
The second impact is the loss of point-in-time recovery specifically. Even teams that keep occasional manual snapshots lose the ability to rewind to an arbitrary second when backups are off. Manual snapshots are point-in-time photographs taken whenever someone remembers; automated backups with PITR let you restore to the instant just before a known-bad event. The difference between "restore to last night's snapshot" and "restore to 14:42:09 just before the bad deploy" is often the difference between losing a day of customer transactions and losing none.
The third impact is compliance, audit, and insurance exposure. Most data-protection frameworks, customer contracts, and cyber-insurance policies assume recoverable backups exist for systems holding regulated or business-critical data. A production database with backups disabled is a finding waiting to happen: it can fail an audit, breach a data-handling commitment, or void an insurance claim at exactly the moment a payout matters. The technical gap and the contractual gap are the same gap.
The cost impact, unusually, runs almost to zero — which is what makes a disabled backup so hard to justify. Backup storage is free up to the database's own allocated size and only a few cents per GB-month beyond that, and the backup window has negligible performance cost (none at all on Multi-AZ). There is no meaningful saving from leaving backups off; the only outcomes are an uninsured liability if the database holds real data, or a trivial non-issue if it's a genuine throwaway. That asymmetry — unbounded downside, near-zero cost to remove it — is why disabling backups is almost never the right call outside truly ephemeral databases.
How do you enable RDS backups safely?
Remediation is a four-step loop: inventory the instances with backups off, set a retention window matched to each database's data class, enable backups with an off-peak window, and prevent regressions so new databases launch protected.
1. Inventory every instance with BackupRetentionPeriod at 0
Pull every RDS DB instance where BackupRetentionPeriod equals 0, across every region and account. For each, capture engine, instance class, Multi-AZ status, allocated storage, and an environment or data-class tag. Anything holding customer, financial, or otherwise real data is a must-fix; only genuinely disposable test, CI, or scratch databases are candidates to stay off. The Multi-AZ flag tells you whether enabling will have any primary-side impact (it won't, if Multi-AZ is true).
2. Choose a retention window matched to the data class
Retention can be 1 to 35 days. Pick it from how far back the business might realistically need to recover, not from cost (which is negligible either way). Transactional and customer-facing databases commonly sit at 7–14 days; systems with stricter recovery or compliance needs go higher, up to the 35-day maximum. Record the chosen window against each instance (a BackupRetentionDays or data-class tag works well) so the standard is auditable and not re-decided every scan.
3. Enable backups with an off-peak backup window
Use modify-db-instance --backup-retention-period N --preferred-backup-window HH:MM-HH:MM. The instance stays online and serving; the only side effect is one immediate full backup when the feature is first turned on. Put the window in the service's quiet hours — on Multi-AZ instances the backup runs against the standby so the primary is untouched, and on single-AZ instances the brief I/O pause lands outside peak. Use --apply-immediately for urgent production gaps, or --no-apply-immediately to let it settle in the next maintenance window.
4. Prevent regressions and layer in centralized backup where needed
Make non-zero retention the default in provisioning templates (CloudFormation/Terraform module defaults) and enforce it with an AWS Config rule (db-instance-backup-enabled) or an SCP so new production databases can't launch with backups off. For cross-account, cross-region, or longer-than-35-day retention, add a centralized AWS Backup plan on top — it complements per-instance automated backups rather than replacing them. For the rare database you intentionally leave unbacked, record a documented exception so the dashboard reflects deliberate decisions, not blind spots.
# 1. List every instance running with automated backups disabled.
aws rds describe-db-instances \
--query 'DBInstances[?BackupRetentionPeriod==`0`].DBInstanceIdentifier' \
--output text
# 3. Enable a 7-day window on a production instance, off-peak, immediately (no downtime).
aws rds modify-db-instance \
--db-instance-identifier payments-ledger-db \
--backup-retention-period 7 \
--preferred-backup-window 03:00-04:00 \
--apply-immediately
# 3. Confirm point-in-time recovery is live (LatestRestorableTime advances).
aws rds wait db-instance-available \
--db-instance-identifier payments-ledger-db
aws rds describe-db-instances \
--db-instance-identifier payments-ledger-db \
--query 'DBInstances[0].[BackupRetentionPeriod,LatestRestorableTime]' \
--output text Quick quiz
Question 1 of 5A scan flags payments-ledger-db, a standalone Postgres instance backing live settlement, with BackupRetentionPeriod=0. What's the right next move?
You scored
0 / 5
Keep learning
Go deeper on RDS automated backups, point-in-time recovery, the pricing that makes them nearly free, and how centralized AWS Backup layers on top.
- Working with backups in Amazon RDS How automated backups, the backup window, retention (1–35 days), and point-in-time recovery work, including what a retention period of 0 disables.
- Restoring a DB instance to a specified time (PITR) The point-in-time restore procedure that automated backups enable — restoring to any second within the retention window.
- Amazon RDS pricing — backup storage Confirms backup storage is free up to the database's allocated size, with a per-GB-month charge only beyond it — why this protection is essentially free.
- AWS Backup with Amazon RDS How centralized AWS Backup plans add cross-account, cross-region, and longer-term retention on top of per-instance automated backups.
You've completed Enable automated backups on RDS. You now know how the daily snapshot and continuous transaction-log capture combine to give you point-in-time recovery to any second in the window, why a BackupRetentionPeriod of 0 silently removes that capability entirely, the exact modify-db-instance --backup-retention-period flag that fixes it with no downtime, why the backup window has negligible performance cost (none on Multi-AZ), and why the near-zero cost makes leaving backups off almost never the right call outside true throwaways. Next time the check fires, you'll know whether to enable the window or record a deliberate exception.
Back to the library