The rule is older than most of the infrastructure it gets applied to. Photographer Peter Krogh wrote it down in 2009, in a book about managing digital photo archives, and it has survived largely unchanged:
3 copies of your data, on 2 different media, with 1 off-site.
It survived because it is not really about counting. Each number encodes a different failure mode, and the counting is just a memorable way to check you have covered all three. When people apply the rule literally in a cloud environment they usually satisfy the arithmetic and none of the intent.
What each number is actually for
3 copies — protects against a single failure. The production data plus two backups. Two rather than one because the second exists for the case where the first backup is also bad, which is far more common than anyone expects: a corrupted archive, a dump that has been silently empty for weeks, a snapshot taken mid-write.
2 media — protects against a correlated failure. In 2009 this meant "don't put both copies on the same kind of hard drive," because drives from the same batch fail in similar ways at similar ages. The modern reading is broader and more useful: two independent failure domains. Two copies that fail for the same reason are one copy with extra steps.
1 off-site — protects against losing a whole location. Fire, flood, theft, a datacentre going down. Everything in one building dies with the building.
Where cloud breaks the arithmetic
Here is a setup that passes the rule on a whiteboard and fails in practice:
- Production database in AWS
us-east-1 - Automated RDS snapshots, same account
- Cross-region replica in
us-west-2, same account
Three copies. Two regions. One "off-site." Every box ticked.
Now take one compromised root credential, or one closed account after a billing dispute, or one over-broad Terraform apply, and all three disappear together. They were never independent — they shared a control plane, a credential boundary, and a billing relationship. Under the rule's actual intent, that is one copy.
This is the same argument that applies to S3 versioning, DynamoDB PITR and provider VPS snapshots. All are genuinely useful. None of them is an off-site copy, because "site" in a cloud context is not geography.
The modern translation:
| 2009 | Today |
|---|---|
| 2 media | 2 failure domains — different providers, different credentials, different billing |
| Off-site | Outside the account, ideally outside the provider |
| Fire and theft | Credential compromise, account closure, operator error, ransomware |
Ask "what single event destroys this copy?" for each one you hold. If two copies answer the same, you have one.
3-2-1-1-0
Ransomware pushed the rule to grow two digits, and both additions are earned:
- 3 copies of the data
- 2 different media or failure domains
- 1 off-site
- 1 immutable or offline
- 0 errors — verified by an actual restore
The extra 1 exists because modern ransomware deletes backups before encrypting anything, using credentials it already stole. A copy that your production credentials can delete is a copy the attacker can delete. See immutable backups for what actually holds up here.
The 0 exists because most of the rule is about having copies, and none of it is about whether they work. An unverified backup is a hypothesis. Testing it is the only step that converts the hypothesis into a fact, and it is the step teams skip most.
A worked example
Take an ordinary setup — Postgres and some uploaded files on a VPS — and apply the rule with intent rather than arithmetic.
Copy 1: production. The live database and the files on the server. This is the copy you are protecting, not a backup.
Copy 2: provider snapshots. Nightly droplet snapshots from your host. Fast to restore, useful for "I broke the server at 2am," and in the same account and the same failure domain as production. Keep it — it is the fastest recovery you have for the common case — and do not count it as your off-site copy.
Copy 3: off-provider snapshots. A nightly dump pushed to storage with credentials your VPS provider does not issue and your production server cannot delete:
import { BackupClient } from "@lighthouse-web3/baas-js-sdk";
const client = new BackupClient({
apiKey: process.env.LH_API_KEY, // scoped to write + read only
workspaceId: process.env.LH_WORKSPACE_ID,
});
await client.backup(["./db-dumps", "./uploads"], {
description: "nightly",
tags: { type: "db-backup", env: "prod" },
encryption: {
keyfilePath: "/secure/lh.keyfile",
passphrase: process.env.LH_KEYFILE_PASSPHRASE,
},
});
Scoring it:
- 3 copies — production, provider snapshot, off-provider snapshot ✅
- 2 failure domains — one provider account, one unrelated account ✅
- 1 off-site — the off-provider copy, which survives losing the VPS account ✅
- 1 immutable — snapshots cannot be modified after creation, and the key on the server has no delete permission ✅
- 0 errors — only if you actually run a restore drill ⬜
That last box is the one you have to keep ticking. Everything above it is a one-time setup; verification is a habit.
The common ways it goes wrong
Counting copies that share a credential. The most frequent failure, and the reason the "2 media" clause was ever written.
Treating another region as off-site. Regions protect against a region failing. They do nothing about the account that owns both.
Backing up to a mounted share. A NAS mounted on the machine it backs up is a directory. Ransomware encrypts directories.
Retention shorter than attacker dwell time. Intruders commonly sit quiet for weeks. A 7-day window means waiting them out is a viable strategy. Thirty days is a more defensible floor.
Backing up the corruption. If bad data reaches production and every copy is a faithful mirror taken since, you have three copies of the problem. Versioned point-in-time snapshots are what let you go back to before it started — this is the difference between backup and replication, and it is the whole reason replication is not a backup.
Never restoring. Discussed above, and still the most common of all.
Is three copies always right?
No, and treating it as a floor for everything wastes money.
The rule is a default for data whose loss would be serious. Scale it to what the data is actually worth:
| Data | Sensible target |
|---|---|
| Cache that rebuilds from a database | 0 backups — write a warm-up script |
| Dev and staging databases | 1 copy, short retention |
| Production application data | Full 3-2-1-1-0 |
| Financial or regulated records | 3-2-1-1-0, plus whatever the regulation says |
| Data you could not operate without for a day | 3-2-1-1-0, plus a tested RTO |
The honest test is not "how many copies do I have" but "how long could I run without this, and what would it cost me?" RPO and RTO are how you turn that into numbers you can design against.
The one-sentence version
Three copies is the memorable part; failure independence is the actual idea. If one event — one credential, one account, one provider, one building — can take out everything you hold, then however many copies you counted, you have one.
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.