Guide

RPO vs RTO: the two numbers your backup schedule is already choosing for you

RPO is how much data you lose, RTO is how long you're down. Most teams have never measured either — and the gap between the assumed RTO and the real one is where outages get expensive.

6 min readBackup Data

Every backup setup has an RPO and an RTO whether anyone wrote them down or not. A nightly cron job at 2am with a four-hour restore procedure has an RPO of 24 hours and an RTO of four hours. Nobody chose those numbers; they fell out of a schedule someone picked because 2am seemed quiet.

The two terms sound like consultant vocabulary and are genuinely useful, because they separate two questions that get conflated constantly.

The definitions, without the jargon

RPO — Recovery Point Objective. How much data can you afford to lose?

Measured backwards in time from the failure. If you back up nightly at 2am and the database dies at 5pm, you lose fifteen hours of work. Your RPO is 24 hours — the worst case, not the average.

RPO is decided by backup frequency. Nothing else moves it. Want a one-hour RPO? Back up hourly. There is no clever configuration that gets you a tighter RPO than your backup interval.

RTO — Recovery Time Objective. How long can you be down?

Measured forwards from the failure to the moment service is restored. Not until the files finish downloading — until users can use the system again. That includes noticing the problem, deciding to restore, finding the right snapshot, restoring it, loading it into an engine, starting the application, and verifying it works.

RTO is decided by your restore procedure, and by whether anyone has ever run it.

        RPO ←────────── failure ──────────→ RTO
   how much data          the moment        how long until
   you lose               it breaks         you're back

They are independent. You can have an excellent RPO and a terrible RTO — hourly backups that take six hours to restore. The reverse is just as common: a fast, well-rehearsed restore of a backup that is a week old.

The number almost everyone gets wrong

Ask a team their RTO and you will usually get an estimate. Ask when they last measured it and the answer is usually never.

This gap is not small. Estimates tend to account for the restore command and nothing else. The measured number includes:

  • Time to notice (monitoring alert, or a customer email?)
  • Time to decide to restore, which on a production database involves a human being sure
  • Finding the right snapshot — the newest one is not always the one you want
  • Download and decrypt
  • Loading into an engine, which is often the longest single step
  • Schema migrations, index rebuilds, cache warming
  • Starting the application and confirming it actually works

A team that says "about twenty minutes" and measures four hours has not made a small error. They have built an entire incident plan, and possibly customer commitments, on a number that was never true.

The only way to know your RTO is with a stopwatch during a restore drill. Start it at "we decide to restore," stop it at "a user could log in." Write the number down. Do it again next quarter, because it grows with your data.

Choosing targets

Work backwards from cost, not from what sounds impressive. The right question is "what does an hour of this outage cost us, and what would it cost to halve it?"

WorkloadTypical RPOTypical RTO
Cache, rebuildable∞ — don't back it upMinutes, rebuild from source
Dev / staging24hBest effort
Internal tooling24h4–8h
Production app database1–6h1–4h
Payments, orders, anything financialMinutesUnder an hour
Regulated recordsWhatever the regulation saysWhatever the regulation says

Two things to notice.

Tightening RPO is usually cheap. Tightening RTO usually is not. Going from daily to hourly backups is a cron change, and with deduplication and incremental uploads, twenty-four snapshots a day cost close to what one costs — a barely-changed dump ships only its delta. Going from a four-hour RTO to a one-hour RTO often means standing up a warm replica, which is real money and real complexity.

So when budget is limited, tighten RPO first. It is the cheaper win by a wide margin.

An RPO of zero means replication, not backups. If you cannot lose a single transaction, you need synchronous replication or a hot standby. That is a different technology solving a different problem — and note that replication is not a backup, because it faithfully replicates DROP TABLE in milliseconds. You want both: replication for availability, backups for recovery from mistakes and corruption.

Making the numbers real

Improving RPO is a schedule change:

# 0 2 * * *      → RPO 24h
# 0 */6 * * *    → RPO 6h
0 * * * * backup /opt/backup/run.sh >> /var/log/backup.log 2>&1   # RPO 1h

This is affordable precisely because content-defined chunking means the second backup of the day uploads only what changed:

await client.backup(["./db-dumps"], {
  description: "hourly",
  tags: { type: "db-backup", env: "prod" },
});

Just keep the dump path stable between runs — a dated filename makes every backup look brand new and throws away the deduplication that made hourly affordable.

Improving RTO is procedural, and the wins are rarely technical:

  • Write the runbook before you need it. Most of a bad RTO is people working out what to do.
  • Rehearse it. The second restore is always dramatically faster than the first.
  • Know which snapshot you want. Tagging backups (env, type, source) turns "which of these 300 is the right one" into a filter.
  • Restore into a prepared target. An empty database with extensions and roles already created removes a step you would otherwise do under pressure.
  • Decide the decision in advance. Agree ahead of time who can authorise a restore, so the clock is not running while people look for that person.

Where the numbers come from in an incident

A practical detail that catches people out: your RPO is only as good as your newest verified backup, not your newest backup.

If last night's job ran and produced a subtly broken dump, your real recovery point is the night before — and you find that out at the worst possible moment, having already spent the first chunk of your RTO on a restore that failed. This is why "0 errors" is part of 3-2-1-1-0 and why drills are not optional.

Similarly, an RTO measured on a 2 GB database tells you very little about restoring 200 GB. Re-measure as data grows. The number is not a constant.

Writing them down

Two lines per system, somewhere the on-call person will find them:

Postgres (orders)     RPO 1h   RTO 90m   last drill 2026-08-01, 84m measured
Uploads (S3 mirror)   RPO 24h  RTO 4h    last drill 2026-07-15, 3h20m measured
Redis (sessions)      RPO 24h  RTO 15m   last drill 2026-08-01, 11m measured

That third column is the one that makes this real. A target with no measurement beside it is an aspiration, and aspirations do not restore databases.

The short version

RPO is how much data you lose, and your backup schedule sets it. RTO is how long you're down, and only a stopwatch tells you what it is.

Most teams can improve RPO this afternoon for almost nothing, and most teams are wrong about their RTO by a factor they would find alarming. Both facts are worth acting on before the day you need them to be true.

Start with the free tier: backupdata.io has 5 GB free, no card, and the 10-minute quickstart gets you to a first verified snapshot today.

Start with the free tier

5 GB free, no card required. Point your existing dump at Backup Data and get to a first verified snapshot in about ten minutes.

Read the quickstart

Keep reading

Guide · 7 minAutomating backups with GitHub Actions (and when not to)Guide · 6 minBack up model checkpoints before your spot instance disappearsGuide · 7 minBacking up a Linux server without backing up the whole disk