Skip to content

RDS point-in-time restore: what it can rewind — and what it cannot

RDS point-in-time restore replays transaction logs to any second inside your retention window, into a new instance. What PITR actually recovers, what it cannot, and the runbook for a clean restore.

RDS point-in-time restore (PITR) can rebuild your database as it existed at any second inside your backup retention window — typically up to about five minutes before now. It cannot restore in place, cannot rewind a single table by itself, cannot go back further than the retention window, and cannot save you if the backups themselves were deleted along with the instance. Knowing those four boundaries before the bad day is the difference between a 45-minute recovery and a career-defining afternoon.

What’s happening

When BackupRetentionPeriod is at least 1 day, RDS continuously ships transaction logs to S3, roughly every five minutes, on top of the daily automated snapshot. A PITR takes the nearest snapshot before your target time and replays logs forward to the exact second you asked for. Two timestamps define your real window: EarliestRestorableTime (bounded by retention, 1–35 days) and LatestRestorableTime (usually now minus a few minutes, because the latest log batch is still in flight).

What PITR gives you: recovery from a dropped table, a bad migration, a fat-fingered UPDATE without a WHERE, or application-level corruption — as long as you know roughly when it happened and it happened inside the window.

What PITR does not give you:

  • In-place rewind. Like a snapshot restore, PITR always creates a new instance. Your production instance keeps existing, and all the new-instance configuration surprises — default parameter group, default security group, new endpoint — apply here too.
  • Table-level restore. You restore the whole instance to the target time, then copy the one table you need back into production yourself.
  • Anything before the window. Retention of 7 days means day 8 is gone from PITR’s reach; only manual snapshots go further back.
  • Deleted-instance recovery, unless backups survived. Deleting an instance normally deletes its automated backups after the retention grace, unless retained automated backups are kept or you took a final snapshot. If both were skipped, PITR has nothing to replay.
  • Un-replicated externalities. Data your app wrote to S3, queues, or third parties after the restore point stays written; PITR rewinds only the database.

The mechanics and engine notes are in the RDS backup documentation at https://docs.aws.amazon.com/rds/. How to design the retention and snapshot strategy around PITR — windows, cross-region copies, and the quarterly drill — is covered in the RDS PITR + snapshot strategy runbook.

What to check first

  • Your actual window — EarliestRestorableTime and LatestRestorableTime, not what you assume retention is set to.
  • The damage timestamp — from application logs, CloudTrail, or audit logs. Restore to just before it, with a minute of margin.
  • Whether the instance still exists — a live instance means normal PITR; a deleted one means checking retained automated backups fast.
  • Production configuration names — parameter group, security groups, subnet group, ready to pass explicitly.
  • Timezone discipline — restore times are UTC; a timezone slip restores five hours of the wrong data.

How to verify

aws rds describe-db-instances --db-instance-identifier prod-db \
  --query 'DBInstances[0].[BackupRetentionPeriod,LatestRestorableTime]'

aws rds describe-db-instances --db-instance-identifier prod-db \
  --query 'DBInstances[0].EarliestRestorableTime'

For a deleted instance, check whether retained automated backups still exist:

aws rds describe-db-instance-automated-backups \
  --query 'DBInstanceAutomatedBackups[].[DBInstanceIdentifier,RestoreWindow,Status]'

In the console the same numbers live under RDS > Automated backups, and on a live instance under RDS > Databases > (instance) > Maintenance & backups. Pin down the damage time with CloudTrail if the cause was an API action, or the engine audit/general log if it was SQL.

The runbook

  1. Freeze the blast radius. If bad writes are still happening, stop the offending job or revoke the credential first — restoring under continuing damage just moves the target.

  2. Fix the target time in UTC and write it down. One authoritative timestamp, agreed in the incident channel, one minute before the first bad write.

  3. Restore to a new instance with explicit configuration:

    aws rds restore-db-instance-to-point-in-time \
      --source-db-instance-identifier prod-db \
      --target-db-instance-identifier prod-db-pitr \
      --restore-time 2026-07-03T18:31:00Z \
      --db-subnet-group-name prod-db-subnets \
      --vpc-security-group-ids sg-0abc123def456 \
      --db-parameter-group-name prod-pg16-params \
      --no-publicly-accessible

    Use --use-latest-restorable-time instead of --restore-time when the instance died and you simply want everything recoverable.

  4. Validate against the damage. Confirm the dropped table exists, the corrupted rows are clean, and the latest legitimate transactions before the target time are present.

  5. Choose full cutover or surgical copy. Whole database poisoned: cut applications over to the restored instance. One table or a few rows: export from the restored copy (pg_dump --table, mysqldump with a table list) and load into production, which avoids losing the good writes that happened after the incident.

  6. Reconcile the gap. Writes between the restore point and the cutover are gone from the database — pull them from application logs or queues where possible, and tell the business what the gap is honestly.

  7. Clean up on a date. The restored instance bills like any other; snapshot it, schedule its deletion, and close the loop.

When this is the wrong move

If the incident was hardware failure rather than bad data, Multi-AZ failover already handled it — PITR would only lose you the last few minutes for no benefit. If the damage predates your retention window, stop and look at manual snapshots or exported data instead. And if you need the same recent state repeatedly for testing rather than recovery, Aurora fast clones or a snapshot restore are cheaper and faster than repeated PITRs.

Common mistakes

  • Restoring to the time you noticed the problem instead of the time it started — hours of corruption come back with the data.
  • Doing a full cutover for a one-table incident, discarding every good write since the restore point.
  • Losing the restore to timezone confusion — --restore-time is UTC, your incident channel probably is not.
  • Assuming PITR covers a deleted instance when nobody enabled retained automated backups and nobody took a final snapshot.

Prevention

  • Set retention to cover realistic detection lag — 7 days minimum for production; 1 day means “notice it today or lose it”.
  • Alarm if LatestRestorableTime falls more than 10–15 minutes behind now; that is your log shipping falling behind.
  • Enable deletion protection and retained automated backups on production instances.
  • Drill a PITR quarterly and time it — restore duration scales with database size and log replay distance, and the business deserves a real RTO number.

PITR is the feature that turns “someone dropped the table at 2:30” from a disaster into a procedure — but only inside its window, only to a new instance, and only if the backups outlived the mistake. 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.