How to Build a 3-2-1 Backup Plan for Your Website

How to Build a 3-2-1 Backup Plan for Your Website

The 3-2-1 backup strategy website owners should use means keeping three copies of your data, on two different kinds of storage, with one copy offsite. For a website that translates to: the live site, a local snapshot on separate hardware, and a remote copy that the live host cannot reach or delete. The reason this matters is that most site disasters are not disk failures, they are deletions and corruption that replicate instantly to every backup your host controls.

Why the 3-2-1 Backup Strategy Website Owners Use Beats a Host Snapshot

Control panel backups feel reassuring because they are one click away. The problem is where they live. If the snapshot sits on the same account, the same provider, or the same credentials as the live site, then one compromised admin login, one billing dispute, or one bad rm -rf removes the site and its backups together. Ransomware operators know this and go after the backup panel first, because that is where the leverage is.

The second problem is versioning. A backup that only ever holds the most recent state is a mirror, not a backup. If a corrupted plugin has been quietly writing bad rows into your database for three weeks, a nightly overwrite gives you three weeks of bad data and a single good copy that has already aged out. You want a retention window long enough to notice the damage and reach back past it.

Designing the Three Copies

Copy one is the live site. Do not count it as a backup, it is the thing you are protecting.

Copy two should be a pull, not a push. The distinction matters: if your web server holds credentials that can write to the backup target, then an attacker on the web server can destroy the backup. Invert it. Run the backup job on a separate machine that reaches into the web server, or into a read only replica, and writes to storage the web server has no key for. If you must push, give the sender an append only or write once credential so it can add objects but not delete them.

Copy three goes offsite, meaning a different provider, a different account, and ideally a different jurisdiction from the live host. Object storage with versioning and object lock enabled is the usual answer. Versioning keeps every prior copy of an object when it is overwritten, and object lock in compliance mode makes those versions immutable for a retention period you set, even by an administrator. That is the property that survives ransomware: the attacker can encrypt your live site, but cannot shorten the retention clock or delete the locked versions.

Files and Databases Need Different Treatment

Files are straightforward to sync. Databases are not, because copying the data directory of a running MySQL or MariaDB instance gives you a torn, unusable snapshot. Dump it consistently instead, and pipe the dump straight into your offsite storage so nothing sensitive lingers on disk:

mysqldump --single-transaction --quick --routines \
  --defaults-extra-file=/etc/backup.cnf mydb \
  | gzip -9 \
  | aws s3 cp - s3://my-offsite-backups/db/$(date +%F).sql.gz \
      --endpoint-url https://storage.example.net

The --single-transaction flag gives you a consistent read of InnoDB tables without locking writers, and --quick streams rows instead of buffering them in memory. Keep the credentials in /etc/backup.cnf with mode 0600 rather than on the command line, where they would show up in the process list. The date in the object key is what gives you versions in a plain filesystem or bucket listing.

Versioning, Retention, and the Restore You Never Tested

Versioning without a retention policy becomes a storage bill and a search problem. Decide how far back you need to reach. A common shape is daily copies for a couple of weeks, weekly copies for a couple of months, and monthly copies kept longer. On object storage you can express that as a lifecycle rule that transitions old versions to cheaper storage and expires them after a set number of days. Write the rule down somewhere outside the storage account, because you will need to explain it during an incident.

Immutability is the part people skip. On S3 compatible storage, object lock requires versioning to be on and is set per bucket at creation time, so plan the bucket before you fill it. A minimal lifecycle policy looks like this:

<LifecycleConfiguration>
  <Rule>
    <ID>expire-old-db-versions</ID>
    <Filter><Prefix>db/</Prefix></Filter>
    <Status>Enabled</Status>
    <NoncurrentVersionExpiration>
      <NoncurrentDays>120</NoncurrentDays>
    </NoncurrentVersionExpiration>
  </Rule>
</LifecycleConfiguration>

That rule deletes noncurrent versions of database objects after 120 days while leaving the current version alone. Pair it with a bucket level default retention so new objects are locked for, say, 30 days. The numbers are yours to choose; the point is that they are decided in advance and enforced by the storage system rather than by a script that an attacker can edit.

Integrity Checks and the Restore Drill

An untested backup is a hypothesis. Two habits turn it into a plan. First, checksum each artifact at creation and verify it at the destination, so you know the transfer was not truncated. Second, restore on a schedule into a throwaway environment and actually load the database. A restore that fails at 3am is a much worse discovery than one that fails on a Tuesday afternoon when nobody is paging you.

Keep the restore procedure in version control next to your application code, not in a wiki that only one person can find. Include the exact commands, the credential locations, and the order of operations. During a real incident, the person running the restore will be tired and under pressure, and a written sequence is worth more than anyone's memory.

What to Do Next

Start by listing every place your site's data currently exists and marking which of those places a compromised admin account could delete. Then pick one offsite bucket, turn on versioning and object lock before you write anything to it, and point a single scripted dump at it tonight. Add the checksum and the restore drill after that, and set a calendar reminder to restore from the offsite copy into a scratch environment on a fixed schedule. The first restore you run will teach you more about your backup design than any amount of planning.

Related articles

Subscribe to our newsletter

Get the latest hosting tips, performance insights, and industry news.