RPO vs RTO: Backup/Restore, Pilot Light, Warm Standby, Multi-Site
10 min readBytePatterns
RPO vs RTO explained: how much data you may lose and how long you may be down, the four AWS disaster recovery strategies, and why replicas copy bad data too.
RPO vs RTO in one line: the recovery point objective is how much recent data you can afford to lose, measured backwards from the failure, and the recovery time objective is how long you can afford to be down, measured forwards from it. The first is set by how often data leaves the primary site; the second by how much of the workload is already running somewhere else. AWS describes four strategies that trade standing cost for smaller numbers on both. Everything below comes from the AWS Well-Architected Reliability Pillar and the disaster recovery whitepaper listed at the end, as of October 2026.
| Strategy | Running in the recovery Region | RPO and RTO, as documented |
|---|---|---|
| Backup and restore | backups only | RPO in hours, RTO in 24 hours or less |
| Pilot light | live data stores; servers not deployed | RPO in minutes, RTO in tens of minutes |
| Warm standby | a scaled-down working copy | RPO in seconds, RTO in minutes |
| Multi-site active/active | the full workload, serving traffic | RPO near zero, RTO potentially zero |
The problem it solves
"We need disaster recovery" is not a requirement anyone can build. Two numbers make it one:
- RTO is the maximum acceptable delay between the interruption and restored service.
- RPO is the maximum acceptable time since the last data recovery point.
Both are business decisions first. A payroll system just before payday and a marketing site have very different answers, and the strategy should be no more stringent than the numbers demand, because every step down the table costs more every day.
The intuition
RPO is about the data that has already left. If the last copy outside the failed Region is a backup from four hours ago, four hours of writes are gone, whatever you do next. Backups bound RPO by their interval; continuous replication bounds it by the replication lag. The Reliability Pillar notes that automated or continuous backups with point-in-time recovery can bring backup-based RPO as low as 5 minutes in some cases.
RTO is about what is already switched on. Each strategy keeps more running in the recovery Region:
- Backup and restore keeps only data. Recovery means deploying infrastructure, ideally from infrastructure as code, deploying the application and restoring the data.
- Pilot light keeps the data stores live and replicated, with core infrastructure provisioned, but application servers are not deployed. It cannot serve a request until they are switched on and scaled out.
- Warm standby runs a scaled-down but fully functional copy that can take traffic immediately, and then scales up. When fully scaled it is called hot standby.
- Multi-site active/active serves traffic from several Regions at once. There is no failover in the usual sense: the failed Region is evacuated.
Replication is not a backup. Continuous replication copies a corrupting write or a deletion just as faithfully as a good one. That is why the documentation says every strategy, active/active included, still needs point-in-time backups, and why recovery from a data disaster always has a recovery point some time before the disaster was discovered.
Watch it run
The lesson animation draws a timeline with the Region failure at zero: RPO bars reach left, RTO bars reach right, one row per strategy. Backup and restore loses four hours and takes eight to recover, pilot light five minutes and thirty, warm standby thirty seconds and five minutes, and active/active almost nothing. The standing cost grows in the opposite direction. A target of 15 minutes and one hour rules out the first row and makes pilot light the cheapest fit. The last frame is the corrupting write.
Disaster Recovery: RPO & RTO
Step 1 of 9
Two numbers decide disaster recovery. RPO: how much recent data you can lose. RTO: how long you can be down.
The same interactive animation as the lesson — step through it with the controls.
The code
A toy model of the lesson's timeline, not an AWS service. Each strategy is a backup interval, a replication lag, the time to deploy servers, restore data and scale up, and a relative standing cost. All inputs are illustrative, chosen inside the documented ranges. One failure, four outcomes:
# Toy model. Every number is an illustrative input in minutes, not an AWS figure.
STRATEGIES = {
# backup interval, replication lag, time to deploy servers, restore data
# and scale up, and a relative standing cost in the recovery Region
"backup/restore": dict(backup_every=240, lag=None, deploy=300, restore=180, scale=0, cost=1),
"pilot light": dict(backup_every=60, lag=5, deploy=20, restore=0, scale=10, cost=3),
"warm standby": dict(backup_every=60, lag=0.5, deploy=0, restore=0, scale=5, cost=6),
"active/active": dict(backup_every=60, lag=0.02, deploy=0, restore=0, scale=0, cost=10),
}
def recover(s, fail_at):
"""RPO achieved: time between the last recovery point and the failure.
RTO achieved: time from the failure until the recovery Region serves."""
if s["lag"] is None: # only backups reach the other Region
point = fail_at // s["backup_every"] * s["backup_every"]
else: # replicas trail by the lag
point = fail_at - s["lag"]
return fail_at - point, s["deploy"] + s["restore"] + s["scale"]
def fmt(minutes):
if minutes < 1:
return "%ds" % round(minutes * 60)
h, m = divmod(round(minutes), 60)
return ("%dh%02dm" % (h, m)) if h else "%dm" % m
FAIL_AT = 15 * 60 + 59 # the primary Region fails at 15:59
for name, s in STRATEGIES.items():
rpo, rto = recover(s, FAIL_AT)
print("%-15s data lost %-6s down for %s" % (name, fmt(rpo), fmt(rto)))
# backup/restore data lost 3h59m down for 8h00m
# pilot light data lost 5m down for 30m
# warm standby data lost 30s down for 5m
# active/active data lost 1s down for 0s
Choosing is then a filter and a minimum. The second call shows a tighter target pushing the answer up the cost scale, and the third shows that a hard zero is not on the table. The last line is backup and restore's worst case over a whole day: a failure just before the next backup runs.
def cheapest(target_rpo, target_rto, fail_at):
"""Lowest standing cost that meets both objectives on this failure."""
fits = [(s["cost"], name) for name, s in STRATEGIES.items()
if recover(s, fail_at)[0] <= target_rpo and recover(s, fail_at)[1] <= target_rto]
return min(fits)[1] if fits else None
print(cheapest(15, 60, FAIL_AT), "|", cheapest(1, 10, FAIL_AT), "|", cheapest(0, 0, FAIL_AT))
# The worst case for backups is a failure just before the next one runs:
print(max(recover(STRATEGIES["backup/restore"], t)[0] for t in range(0, 24 * 60)))
# pilot light | warm standby | None
# 239
Now the failure that replication cannot fix. Every replica receives the bad write within its lag, so the recovery point becomes the last clean backup, and the strategies that were seconds apart a moment ago now differ only by their backup schedule:
# A corrupting write at 10:00, noticed at 11:30. Replication copies it within
# the lag, so every replica is bad too; only a backup taken before 10:00 is clean.
CORRUPT_AT, NOTICED_AT = 10 * 60, 11 * 60 + 30
clock = lambda m: "%02d:%02d" % divmod(m, 60)
def last_clean_backup(backup_every):
return (CORRUPT_AT - 1) // backup_every * backup_every
for name, s in STRATEGIES.items():
if s["lag"] is None:
replica = "no replica"
else:
replica = "corrupted" if NOTICED_AT - CORRUPT_AT >= s["lag"] else "clean"
point = last_clean_backup(s["backup_every"])
print("%-15s replica %-10s restore to %s, rolls back %s" % (
name, replica, clock(point), fmt(NOTICED_AT - point)))
# Point-in-time recovery every 5 minutes moves the clean point closer, but the
# writes made after the corruption still have to be checked or replayed:
print("PITR every 5m: restore to %s, re-check %s of writes" % (
clock(last_clean_backup(5)), fmt(NOTICED_AT - CORRUPT_AT)))
# backup/restore replica no replica restore to 08:00, rolls back 3h30m
# pilot light replica corrupted restore to 09:00, rolls back 2h30m
# warm standby replica corrupted restore to 09:00, rolls back 2h30m
# active/active replica corrupted restore to 09:00, rolls back 2h30m
# PITR every 5m: restore to 09:55, re-check 1h30m of writes
The complexity
The real costs are the ones the toy reduces to one number:
- Standing cost grows down the table: storage only, then live databases, then a running fleet, then a full second production environment.
- Operational cost grows too. Active/active needs a plan for writes in two Regions, such as routing all writes to one Region, writing locally with last-writer-wins, or partitioning writes by key.
- Recovery work shrinks down the table. Backup and restore depends on many steps succeeding under pressure; warm standby mostly needs scaling.
Where it goes wrong
- Untested recovery. A plan that has never been run has an unknown RTO. Test failover, and test restores.
- Failing over with control-plane calls. The documentation recommends data-plane operations during recovery, such as Route 53 health checks and Application Recovery Controller routing controls, because data planes have higher availability goals than control planes.
- No capacity in the recovery Region. Pilot light and warm standby need to scale up. Check service quotas there, and consider capacity reservations.
- Replicas instead of backups. Corruption replicates. Keep point-in-time backups in the recovery Region too.
- Automatic failover on a false alarm. A failover itself costs downtime and some data; many teams start it by hand but automate every step.
When it shows up in interviews
Usually as a follow-up to a design: "the Region is gone, what now?" Questions 20 and 21 in AWS interview questions, part 2 give the short definitions; the interviewer then wants numbers and a choice. Replication lag, the mechanism behind a small RPO, is covered in database replication explained, and the strategies are walked through in the disaster recovery lesson.
How to say it in an interview
"I start by asking for the RPO and RTO, because they set the cost. RPO is how much data we can lose, so it depends on how often data leaves the Region: backup interval or replication lag. RTO is how long we can be down, so it depends on how much is already running. Backup and restore is cheapest, with RPO in hours and RTO up to a day. Pilot light keeps data live but servers off. Warm standby runs a small working copy, and active/active serves from every Region. Whatever I pick, I keep point-in-time backups, because a corrupting write replicates."
Frequently asked questions
What is the difference between RPO and RTO?
RPO, the recovery point objective, is the maximum acceptable time since the last data recovery point, so it measures data loss backwards from the failure. RTO, the recovery time objective, is the maximum acceptable delay between the interruption and restored service, so it measures downtime forwards from the failure.
What is the difference between pilot light and warm standby?
Both keep copies of the data in the recovery Region. Pilot light cannot serve requests until servers are deployed or switched on and scaled out. Warm standby already runs a scaled-down working copy that can take traffic immediately and only needs to scale up, so its RTO is lower and its cost higher.
Does active/active need backups?
Yes. Replication copies corruption and deletions to every Region within seconds, so it protects against losing a Region, not against bad data. After a data disaster, the recovery point is the last clean point-in-time backup, which is always some time before the problem was discovered.
Sources
- REL13-BP01 Define recovery objectives for downtime and data loss — AWS Documentation
- REL13-BP02 Use defined recovery strategies to meet the recovery objectives — AWS Documentation
- Business Continuity Plan (BCP) — AWS Documentation
- Disaster recovery options in the cloud — AWS Documentation