Part 3 of 3 in the Surviving ransomware series. Part 1: Backups an attacker can’t delete. Part 2: Segmentation and limiting lateral movement.
Ask a team for its recovery time objective and you’ll usually get a confident number, often 4 hours or 24 hours. Ask when they last restored a whole system from backup and timed it, and the confidence fades. In my experience the RTO on the slide and the recovery time you’d actually get differ by a factor of several, and nobody finds out until the day it matters.
This is the final part of the series. Part 1 was about backups an attacker can’t delete, and part 2 about segmentation that limits how much gets hit. Now the unglamorous question: once you have clean backups, how long does it really take to be running again?
Two numbers, defined honestly

The recovery point objective (RPO) is how much data you can afford to lose, measured as time between the last good copy and the incident. The recovery time objective (RTO) is how long you can afford to be down. Both are business decisions. Neither is something the backup software sets for you.
The trap is that people derive RTO from the time it takes to restore one file or one VM, then quietly assume the whole estate restores in parallel at that speed. It doesn’t, for two reasons: bandwidth and dependencies.
Do the arithmetic before the drill
Restore throughput is usually far below the vendor’s quoted ingest speed, because restores are bottlenecked by whatever’s slowest: deduplication rehydration, the network link, the target storage’s write rate, or the cloud egress path. Measure it, then do the multiplication.
# Wall-clock hours to move data at a sustained restore rate
def restore_hours(terabytes, mb_per_sec):
return terabytes * 1_000_000 / mb_per_sec / 3600
for tb, rate in [(5, 500), (50, 500), (50, 200), (200, 1000)]:
print(f"{tb:>4} TB at {rate:>4} MB/s: {restore_hours(tb, rate):6.1f} h")
5 TB at 500 MB/s: 2.8 h
50 TB at 500 MB/s: 27.8 h
50 TB at 200 MB/s: 69.4 h
200 TB at 1000 MB/s: 55.6 h
If your critical data is 50 TB and your measured restore rate from the immutable tier is 200 MB/s, a 24-hour RTO isn’t achievable, regardless of how good everything else is. You find that out with a calculator in five minutes, or during an incident in three days.
Dependencies decide the order
You can’t restore the order system until there’s something for it to authenticate against. A realistic recovery runs in layers. First the backup infrastructure itself has to be up, along with its catalogue and its encryption keys. If the backup server was encrypted too, you’re rebuilding it from scratch before restoring anything else. Then identity and core network services: Active Directory or your identity provider, DNS, DHCP, PKI and time. Then the data stores, then the applications on top of them, then everything else.
Maersk’s NotPetya recovery is the famous example of how fragile that first layer can be. As reported by Wired, its domain controllers had all been wiped except one in Ghana, which survived only because a power outage had taken it offline before the attack. That single machine became the seed for rebuilding the company’s Active Directory. Don’t plan on a lucky power cut.
Write the dependency order down, along with who restores each layer and roughly how long each takes. Then look at the critical path. Sequential layers add up, and the result is usually much longer than the RTO anyone quotes.
Pick a clean restore point
After ransomware, the newest backup is often the wrong one. The attacker may have been inside for days or weeks, with tools planted, accounts created and scheduled tasks waiting. Restoring last night’s backup can restore the intrusion.
This is where the logging work from the Detection engineering series pays off. To pick a restore point you need a reasonably confident time of first compromise for each affected system. Then you restore into an isolated recovery network, scan the restored systems, check them against known indicators from the investigation, reset every credential, and only then reconnect them. Budget time for this. In a real incident it often takes longer than the data copy.
Automate the boring restore tests
A backup you haven’t restored is a hypothesis. The cheapest way to keep testing it is to automate small restores constantly and big ones regularly.
Automated tests should check the application, not just the files. A database restore test that confirms the dump file exists proves very little. One that restores into a scratch instance, runs real queries and records how long it took proves a lot:
#!/usr/bin/env bash
set -euo pipefail
start=$(date +%s)
dropdb --if-exists -h restore-test.internal orders_check
createdb -h restore-test.internal orders_check
pg_restore -h restore-test.internal -d orders_check --jobs=8 \
/restore/latest/orders.dump
# The data should be recent and non-trivial
recent=$(psql -h restore-test.internal -d orders_check -Atc \
"select count(*) from orders where created_at > now() - interval '2 days'")
[ "$recent" -gt 0 ] || { echo "restore is stale or empty"; exit 1; }
echo "restore_seconds=$(( $(date +%s) - start )) recent_rows=$recent"
Run something like this weekly against a randomly chosen system, ship the timing to your metrics system, and alert when a test fails or when restore time creeps past what the RTO allows. Over a few months you get a real, measured recovery time per system, which is worth more than any number on a slide.
Run a full drill at least once a year
Automated tests cover individual systems. They don’t cover the dependency chain, the people, or the coordination. Once a year, more often for critical services, run a drill that restores a meaningful slice of production into an isolated environment from the immutable or offline copies, in dependency order, with the people who’d actually do it.
Assume the worst during the drill: the primary backup server is gone, the identity provider is down, and the wiki with the runbooks is encrypted. Keep printed copies of the recovery runbook, the dependency order, key contacts and break-glass procedures somewhere physical. Have an out-of-band way to communicate, since your email and chat may be part of what’s down.
Time every step. The drill’s output isn’t a pass or fail. It’s a list of measured durations and a list of things that surprised you.
Report the real number
After the drill, publish the measured recovery time next to the RTO, per service, to the people who set the RTO. If they differ, that’s a business decision to make with real data: spend money on faster restores, change the architecture, or accept a longer outage knowingly. Any of those is fine. Finding out during an incident isn’t.
If you only do one thing after reading this, pick a single important system, restore it somewhere isolated this week, and time it. That number will tell you more about your ransomware readiness than any policy document.




