Backup tiers, point-in-time recovery, cold/warm/hot standbys, immutable and air-gapped copies against ransomware, and the rule that an unrestored backup is not a backup.
What this module covers: The failures too large for Phase 3 to absorb — a region gone, a table dropped, a migration that corrupted three hours of data, a ransomware event, an account compromise. Why disaster recovery is not high availability, and why replication is not backup: it copies your mistakes faithfully and immediately. RPO and RTO as business decisions with cost curves, stated per data class rather than once for the company — including the class that needs no backup at all. Point-in-time recovery as the capability that saves you from the DELETE at 14:32, and the silent failure that ends your PITR window without anyone noticing. How ransomware changed the requirements, since an attacker with your credentials deletes the backups first. The standby spectrum and what each tier costs. Then the rule the whole subject reduces to — an unrestored backup is not a backup — with the specific discoveries a restore test makes, the data-loss decision somebody must be authorised to take, and the list of things besides the database that must also be recoverable, including the runbook itself.
Disaster Recovery Is Not High Availability
These get conflated, and the conflation causes a specific, common, catastrophic belief.
High availability
Disaster recovery
Handles
component failure
catastrophic loss
Trigger
automatic
a human decision
Timescale
seconds
minutes to days
Mechanism
replication, failover, multi-AZ
backups, restores, standby sites
Protects against
an instance, disk or zone failing
deletion, corruption, ransomware, region loss
And the belief to demolish:
Replication is not backup, because replication copies your mistakes at the speed of light.
A DELETE FROM orders with no WHERE clause is replicated to all three standbys in milliseconds. A migration that corrupts a column is replicated. A ransomware process encrypting files is replicated. Multi-AZ synchronous replication with automatic failover is excellent engineering that provides zero protection against the most common causes of catastrophic data loss, which are human error and malice rather than hardware.
The distinction is that HA protects against things happening to your infrastructure, and DR protects against things happening through it. You need both, and the second one requires copies that are not connected to the first.
Analogy: a bank's vault versus its archive. The vault is high availability: reinforced, alarmed, with a second door — it protects against the building failing. But if the manager mistakenly shreds a ledger, the vault contains a perfectly-protected copy of the shredding. The archive is disaster recovery: a distinct facility, older copies, kept deliberately behind glass so that today's mistake cannot reach yesterday's record. And the property that makes the archive worth anything is not that documents were placed in it, but that somebody has actually retrieved one and confirmed it is readable.
The Two Numbers, Per Data Class
RPO — recovery point objective: how much data you can afford to lose, expressed as time. It equals the age of your most recent usable recovery point, which in practice equals your replication or backup lag.
RTO — recovery time objective: how long you can afford to be unavailable. And the part teams omit:
text
A five-minute restore procedure behind a forty-minute decision is a forty-five-minute RTO. If your alerting takes ten minutes to notice and nobody is authorised to declare a disaster without a director on the call, your real RTO is an hour regardless of how fast the technology is. Measure and state all four terms, because optimising the fastest one is the usual mistake.
Both numbers are business decisions with cost curves, and they must be set per data class rather than once for the whole company:
Tier
Example
RPO
RTO
Mechanism
0
payment ledger (P-24)
~0
minutes
synchronous replication + PITR + immutable copies
1
primary application database
seconds–minutes
< 1 hour
async replica + PITR
2
analytics warehouse (P-22)
24 hours
days
daily snapshot; rebuildable from source
3
derived data
n/a
rebuild time
no backup at all
Tier 3 is the one worth dwelling on, because it is a real and frequently-missed cost saving. Feed timelines (Module A-14), search indexes (Module P-20), vector indexes (Module P-21), caches (Module F-12), and warehouse-derived tables are all rebuildable from a source of truth. Backing them up costs storage and buys nothing except a faster rebuild — and it can be worse than nothing, because restoring a stale derived copy alongside a current source produces inconsistency nobody expects. The correct DR plan for tier 3 is a rebuild procedure with a measured duration, and Module A-14 deliberately designed timelines as a cache for exactly this reason.
The corollary: know which of your data is a source of truth and which is derived. Teams that cannot answer that per dataset back up everything (expensive) or the wrong things (dangerous).
Backup Types, and Point-in-Time Recovery
For Postgres specifically, two families that are not substitutes:
Logical backup (pg_dump). A portable SQL or archive representation. Good for moving between versions, extracting a single table, and long-term archival. Its limits: slow to restore at scale (it re-executes inserts and rebuilds indexes), it is a snapshot of one instant with no ability to recover to a different one, and — the gotcha — roles and cluster-wide objects are not included in a per-database dump, so a restore into a fresh cluster produces a database whose grants refer to users that do not exist (pg_dumpall --globals-only is the missing half).
Physical backup plus WAL archiving. A base backup of the data directory plus a continuous archive of write-ahead log segments, managed by pgBackRest, WAL-G, Barman or your provider. This gives point-in-time recovery, which is the capability that actually saves you:
text
PITR is what turns "we lost three hours of data" into "we lost forty seconds," and it is the difference between a survivable incident and an existential one. It has a specific, silent failure mode:
A broken WAL archive ends your PITR window and produces no error anyone sees. If archive_command starts failing — expired credentials, a full bucket, a changed permission — Postgres keeps running and keeps retaining the un-archived WAL locally (eventually filling the disk), while your recovery window silently stops advancing. Monitor archive success and the age of the newest archived segment as a first-class alarm, alongside Module P-23's replication-slot retention.
Snapshots (block-level, from the storage layer) are fast and cheap and come with two caveats worth knowing. A snapshot of a running database is crash-consistent, not application-consistent — Postgres will recover from it as it would from a power loss, which usually works and is not the same as a verified backup. And snapshots typically live in the same cloud account and often the same region as the volume, which means the same blast radius as the thing they protect: an account compromise or a region loss takes both.
And know your single-table restore story before you need it. PITR restores a whole cluster, so "undo the deletion of one table" means restoring the entire cluster to a side instance at the target time and copying the table across. That is a slow, disk-hungry procedure and it surprises people mid-incident, which is why a periodic logical dump alongside PITR is worth its cost.
Ransomware Changed the Requirements
The classic 3-2-1 rule — three copies, on two media, one offsite — has been extended for a reason:
3-2-1-1-0: three copies, two locations, one offsite, one immutable or air-gapped, and zero verified errors.
The two additions exist because the modern threat model is different. A ransomware operator with access to your environment has your credentials, and the first thing they do is delete or encrypt the backups, because that is what makes the ransom payable. A backup your compromised credentials can delete is not a backup.
What that requires concretely:
Immutability that even you cannot override. Object lock in compliance mode with a retention period, so no credential — including the account root — can shorten or delete the object before it expires (Module A-11). If an administrator can delete it, so can whoever has the administrator's session.
A separate account or subscription for backup storage, with separate credentials and no trust relationship that lets the production account write or delete there. Blast-radius separation (Module A-13) applied to the one asset whose loss is unrecoverable.
MFA-delete and versioning as additional layers.
Retention longer than your plausible detection time. This is the requirement most often set wrong: if data was silently encrypted or corrupted three weeks ago and your retention is fourteen days, every copy you hold is bad. Dwell time for a compromise is commonly measured in weeks, and a slow data-corruption bug can go unnoticed for longer, so retention needs a long tail — a few daily copies plus weekly and monthly ones extending months back.
Restore tests that use the immutable copy specifically, because that is the path you will actually use in the scenario the copy exists for, and it usually has different access mechanics from the convenient one.
The Standby Spectrum
Strategy
RPO
RTO
Steady-state cost
Backup and restore (cold)
backup interval
hours–days
cheapest — storage only
Pilot light
replication lag
tens of minutes
data replication + minimal infrastructure
Warm standby
replication lag
minutes
a scaled-down full stack
Hot standby / active-active (A-9)
~seconds or 0
~0
a second full environment
Cost rises steeply and non-linearly along that list, which is why different data classes belong at different tiers — a payment ledger at hot standby and an analytics warehouse at backup-and-restore is a coherent architecture, while treating everything as tier 0 is an unfunded aspiration.
Two structural notes carried from Module A-9. A warm or hot standby only helps if the failover path is exercised, and an unrehearsed standby is a line item rather than a plan. And two sites cannot safely fail over automatically — neither can distinguish "the other is down" from "I am partitioned" — so either add a witness in a third failure domain or accept that the declaration is a human decision, which puts it squarely in the RTO's decide term.
An Unrestored Backup Is Not a Backup
This is the rule the entire subject reduces to. A backup job that reports success proves that bytes were written. It does not prove they are readable, complete, restorable with the tools you have, or usable by your application.
Restore tests, automated and scheduled. Monthly at minimum, weekly for tier 0, into a fresh isolated environment, with verification that goes beyond "the restore command exited zero":
row counts against expected ranges,
checksums or aggregate comparisons on key tables,
a smoke test of the application against the restored data — which is the step that catches the problems the database alone cannot show you.
Measure the restore duration, because that is your real RTO. It is almost always longer than assumed, and it is bounded by physics: a 4 TB restore is limited by disk and network throughput, and replaying three days of WAL for a PITR can take hours because replay is largely single-threaded. A team claiming a one-hour RTO whose measured restore takes five hours does not have an RTO, it has a wish.
The discoveries a first restore test makes are remarkably consistent across organisations, and every one of them is cheap to find in a drill and expensive to find in a disaster:
The backup was of the wrong database, or excluded a schema.
The encryption key is not available in the recovery region or account — a classic, and total: an encrypted backup without its key is noise.
The engine version needed to restore is no longer offered by the provider.
A required extension (pgvector, postgis, pg_trgm) is unavailable in the recovery environment, so the restore fails at index creation.
Roles and grants were not in the dump, so the restored database has objects nobody can access.
The restore succeeded and the application could not connect, because an endpoint was hardcoded somewhere.
The runbook references a person who left, or a tool nobody has installed.
Nobody had the permissions to perform the restore except one person.
Automate the verification as a scheduled job, so it is a green or red check rather than a quarterly act of heroism. A restore test that depends on someone remembering will stop happening within two quarters.
The Runbook, and the Decision Somebody Must Be Authorised to Make
Name who declares a disaster. The decide term dominates RTO, and it is dominated by ambiguity about authority. A named on-call role empowered to declare and act, with a defined escalation, converts forty minutes of "should we?" into two minutes of "we are."
The runbook must contain preconditions, steps, verification and a fail-back plan. Failing back is frequently harder than failing over, because data written at the recovery site during the incident must be reconciled into the primary — and a plan that ends at "we are running in the DR region" leaves the hardest half undocumented.
And the data-loss decision is a real decision, not a technicality. With asynchronous replication, promoting the standby means accepting the loss of everything not yet replicated. Someone must be authorised to make that call, and the correct answer depends on the data class in a way that inverts the usual instinct:
For a feed or a session store, promote immediately and accept the loss (Module A-14's availability-first posture).
For a payment ledger, waiting may be correct — Module P-24 put correctness above availability, and losing forty seconds of committed financial transactions can be worse than an extra twenty minutes of downtime. That is a business decision made in advance, written down, not improvised at 3 a.m.
Communication is part of RTO from the customer's perspective. A status page, a defined update cadence, and pre-drafted messages, hosted somewhere that is not on the infrastructure that is down.
What Else Must Be Recoverable
The database is the part everyone plans for. The list that ends recoveries:
Asset
Why it ends the recovery if lost
Encryption keys / KMS
an encrypted backup without its key is noise. Replicate keys to the DR region and test decryption there.
IaC state (Module O-3)
identity of every resource lives there; without it you cannot rebuild reproducibly
Secrets manager contents
the restored application cannot authenticate to anything
DNS control
you cannot redirect traffic to the recovered site
CI/CD and the container registry
you cannot deploy the artefact you need to run
The observability stack
you are recovering blind, and cannot verify success
The runbook itself
the classic: a wiki hosted on the infrastructure that is down
That last row is worth the emphasis it gets everywhere: keep an offline or independently-hosted copy of the recovery documentation, including credentials access paths, contact numbers and the decision authority.
And your RTO cannot beat your dependencies'. A managed database's own recovery SLA, your provider's regional recovery, a payment processor's outage — these bound what you can promise regardless of your engineering (Module O-2's dependency ceiling, applied to recovery). Shared fate matters too: a backup in the same account, region and provider as the primary shares a class of failure with it, and provider-wide incidents do happen.
Testing: the Ladder
Automated restore verification — the CI-style job described above. Non-negotiable, and the cheapest.
Failover drill in staging — the procedure, end to end, with the runbook in hand.
Scheduled production failover — actually run on the real system, announced, in a low-traffic window. This is the step that separates a real DR capability from a documented one, and it is the step most organisations never take.
Unannounced drill (Module O-6's GameDay), which tests detection, decision authority and access under realistic conditions.
Why this matters in production: the recurring disaster-recovery failures are not exotic. A team with three replicas and no backups, believing they were covered, until a bad migration corrupted a column. A backup regime that had run successfully for two years and had never been restored, whose first restore failed on a missing extension. A ransomware event that encrypted the backups in the same account. A retention window shorter than the time it took to notice a corruption bug. A four-hour "one hour RTO" because nobody had timed a 4 TB restore. And a recovery that stalled because the KMS key existed only in the region that was gone. Each is prevented by something in this module, and every one of those preventions is exercised rather than documented.
Where This Shows Up in Your Stack
PostgreSQL: physical base backups plus continuous WAL archiving (pgBackRest, WAL-G, Barman, or the provider's equivalent) for PITR, and alert on archive failures and the age of the newest archived WAL segment — a broken archive_command silently ends your recovery window while filling the primary's disk. Keep periodic pg_dump output for portability and single-table restores, remembering that roles need pg_dumpall --globals-only. Verify that the recovery environment has your extensions and a compatible engine version. And repeat the rule: a streaming replica is not a backup, because it applies your DELETE faithfully.
Object storage: the backup destination, with versioning, object lock in compliance mode, MFA-delete, and a separate account with no write or delete path from production credentials (Modules A-11, A-13). Lifecycle rules for the long tail — daily for a fortnight, weekly for a quarter, monthly for a year — chosen so retention exceeds plausible detection time.
KMS: replicate or mirror keys into the recovery region and test decryption there, because this is the single most common total-failure discovery in a DR drill.
Redis: decide per keyspace. A cache is tier 3 — do not back it up, document the rebuild. Sessions, queues, rate-limiter state used for billing, or a presence store may be real data, in which case AOF persistence plus snapshots to a separate account is the answer (Modules P-14, P-18).
Kafka: retention is not backup — it is a window, and a compacted topic is not an archive. Decide per topic whether it is a source of truth (back it up, or ensure the producer's store is) or a transport for rebuildable data. And note that offsets do not translate across clusters (Module P-23), so a recovery plan must say what consumers do about position.
IaC and CI/CD: state files, module versions, pipeline definitions and registry images are part of the recovery path (Module O-3). An immutable-infrastructure practice pays off here specifically, because rebuilding is the thing you already do daily.
Derived stores — search indexes, vector indexes, feed timelines, warehouse tables: document and time the rebuild rather than backing them up (Modules P-20, P-21, P-22, A-14).
Summary
DR is not HA, and replication is not backup — replication copies a DELETE FROM orders to every standby in milliseconds. HA protects against things happening to your infrastructure; DR protects against things happening through it, and the most common causes of catastrophic loss are human error and malice, not hardware.
RPO is how much data you can lose; RTO is how long you can be down — and RTO = detect + decide + execute + verify, with the first two usually dominating. A five-minute restore behind a forty-minute decision is a forty-five-minute RTO.
Set both per data class, not once for the company. And know which data is a source of truth and which is derived — feed timelines, search and vector indexes, caches and warehouse tables are rebuildable, so the correct plan is a timed rebuild procedure rather than a backup, and restoring a stale derived copy alongside a current source creates inconsistency nobody expects.
Logical dumps are portable and slow to restore, and omit roles (pg_dumpall --globals-only is the missing half). Physical backup plus continuous WAL archiving gives point-in-time recovery, which converts "we lost three hours" into "we lost forty seconds" and is what saves you from a bad migration.
A broken WAL archive silently ends your PITR window while the primary keeps running and retaining WAL locally. Alert on archive success and the age of the newest archived segment.
Snapshots are crash-consistent rather than application-consistent, and usually share the primary's account and region — hence its blast radius. And know your single-table restore story in advance: PITR restores a whole cluster, so recovering one table means restoring to a side instance and copying.
3-2-1-1-0: three copies, two locations, one offsite, one immutable or air-gapped, zero verified errors — because a ransomware operator has your credentials and deletes the backups first. That requires object lock even you cannot override, a separate account with no delete path from production, MFA-delete, and retention longer than your plausible detection time, since a fourteen-day window is useless against a three-week-old corruption.
Test restores from the immutable copy specifically, because that is the path the scenario will use and its access mechanics differ from the convenient one.
The standby spectrum runs from backup-and-restore (hours to days, cheapest) through pilot light and warm standby to hot/active-active (~0 RTO, a second full environment), with cost rising steeply — so different data classes belong at different tiers. An unrehearsed standby is a line item, not a plan, and two sites cannot safely fail over automatically without a witness in a third failure domain.
An unrestored backup is not a backup. Automate scheduled restores into a fresh environment with row counts, checksums and a smoke test of the application against the restored data. Measure the restore duration — that is your real RTO, and it is bounded by throughput and largely single-threaded WAL replay.
First restore tests reliably discover: the wrong database backed up, the encryption key unavailable in the recovery region, an engine version no longer offered, a missing extension, absent roles and grants, a hardcoded endpoint, a runbook naming someone who left, and one person holding the only sufficient permissions.
Name who declares a disaster, because ambiguity about authority is what dominates the decide term. The runbook needs preconditions, steps, verification and a fail-back plan, since reconciling data written at the recovery site is usually the harder half.
The data-loss decision is a business decision made in advance: promote immediately for a feed or session store, but for a payment ledger waiting may be correct, because losing forty seconds of committed financial transactions can be worse than twenty more minutes of downtime.
Also recoverable, or the recovery ends: encryption keys, IaC state, secrets, DNS control, CI/CD and the registry, the observability stack, and the runbook itself — not hosted on the infrastructure that is down.
Your RTO cannot beat your dependencies', and a backup sharing the primary's account, region and provider shares a class of failure with it.
Climb the testing ladder: automated restore verification, a staging failover drill, a scheduled production failover — the step that separates a real capability from a documented one and the one most organisations never take — then an unannounced drill.
The next module, FinOps: Cost Architecture, treats money as a design constraint in the way this module treated recoverability. It covers cost per request and per tenant as first-class metrics, the egress tax that has appeared as a warning in six earlier modules, spot and reserved capacity, storage tiering, and the question worth asking of every scaling decision — whether you are buying capacity or paying to avoid fixing a design flaw.
Knowledge Check
A team runs Postgres with synchronous multi-AZ replication and two asynchronous read replicas, plus daily storage snapshots retained for seven days in the same cloud account. A migration bug silently corrupts a column; the corruption is noticed eighteen days later. What does the module identify?
An organisation states a one-hour RTO for its primary database. A DR drill reveals: alerting took 12 minutes to fire, the on-call engineer spent 35 minutes obtaining authorisation to promote the standby, the promotion took 4 minutes, and application verification took 15 minutes. Total: 66 minutes, with the technology accounting for 4 of them. Where does the module say the effort should go?
A company's backup strategy writes nightly encrypted Postgres backups to object storage in the same cloud account, with versioning enabled and administrator-deletable retention of 30 days. A ransomware operator obtains an administrator credential. What does the module say is inadequate, and what is the required shape?
Test your knowledge with more question sets
Sign in to access a wider variety of questions and get notified when new practice sets are added to this module.
RTO = detect + decide + execute + verify
↑ ↑
the two everyone forgets, and they usually dominate
base backup (Sunday 02:00) + every WAL segment since
→ restore to ANY second in that window
→ "restore to 2026-07-30 14:31:59" — one second before the bad migration