← all builds

The Backup That Proves Itself

backupreliabilityrecovery
Download .md

A sanitised reference implementation. Drop it into Claude Code, point it at what your business runs on, adapt the list. Generic on purpose, with no business specifics and no real file names.

The problem

Most small businesses believe they have a backup until the day they need it. Then the copy turns out to be months old, or it was never checked, or nobody knows how to put it back. A backup you have never restored from is a hope, not a backup.

The idea

Every morning, before the day starts, copy everything the business depends on to an encrypted drive you own. That means the databases, taken safely while they are in use, the code with its full history, the settings and the scheduled jobs. Check every copy after it is made. Fingerprint each file and test that each archive opens. Write a manifest of what landed, keep a month of daily copies plus one a month for a year, stay quiet when it works and be loud when it fails. Keep a step by step restore guide on the drive itself, so getting back does not depend on the computer that just died.

07.00 ──> [copy each database safely] ──> [bundle the code with its history, verify]
                                                   │
                                                   v
      [settings and scheduled jobs] ──> [manifest, a fingerprint for every file]
                                                   │
                                                   v
                  [keep 30 dailies and 12 monthlies] ──> quiet if clean, loud if not

      the restore guide sits on the drive, beside the copies

Minimal reference implementation

# backup_that_proves_itself.py, reference only. Swap in your own list of files.
import hashlib
import sqlite3
import subprocess

def snapshot_database(src, dest):
    """A consistent copy of a live database, taken while the app keeps writing.
    Opened read only, so the backup can never change the original."""
    source = sqlite3.connect(f"file:{src}?mode=ro", uri=True)
    target = sqlite3.connect(dest)
    with target:
        source.backup(target)
    source.close()
    target.close()

def fingerprint(path):
    """A SHA-256 per file goes in the manifest, so a later check can prove the
    copy is still the copy."""
    digest = hashlib.sha256()
    with open(path, "rb") as f:
        for chunk in iter(lambda: f.read(1 << 20), b""):
            digest.update(chunk)
    return digest.hexdigest()

def bundle_repo(repo, dest):
    """The whole history in one file, then proved to open."""
    subprocess.run(["git", "-C", repo, "bundle", "create", dest, "--all"], check=True)
    subprocess.run(["git", "-C", repo, "bundle", "verify", dest], check=True)

Why it works

Adapt it

Built for my own group of businesses, runs every morning at seven, and this is the generalised version. Take it, point it at what your business runs on, tell me what you would add.