Conceptual editorial illustration
AI-generated editorial illustration. The measurements and experiment results are presented separately below.

A retention policy says how many recovery points you want to keep. It does not, by itself, say how much space the next backup will need. When you create and check a new copy before removing an old one, the temporary total can exceed the final seven-copy footprint.

This is a storage-planning guide for independent full-file copies. A historical Server Fault question asks what information is needed to size backup storage instead of choosing an arbitrary source-to-backup ratio. Its environment uses incremental backups; our narrower experiment below uses tiny full copies, so its byte totals are not an answer for that particular system.

Budget the peak, not only the retained total

For this example, all the following files share one storage budget:

rotation peak = existing retained copies
              + new candidate copy
              + isolated restore copy
              + explicit operating reserve

Count each physical copy once. Renaming a completed staging file within this fixture does not create another file copy; copying it between filesystems could require space at both ends. Add other temporary outputs, repository maintenance workspace and ordinary application growth if your real process needs them. If a restore uses a different volume, budget that volume separately.

The reserve is a planning assumption, not a universal percentage. Estimate it from the actual workflow and uncertainty, then compare the peak with usable capacity after unrelated workloads and quotas. A calculation using file lengths omits filesystem metadata and allocation overhead; it is not a guarantee that a disk write will succeed.

A measured seven-copy rotation

On November 7, 2026 (Asia/Shanghai), we ran the downloadable Python script on Linux in a fresh directory. It creates seven synthetic binary files of 128, 144, 96, 160, 112, 176 and 128 KiB. Their date labels, October 31 through November 6, describe a constructed schedule, not a week of historical backup runs. One KiB is 1,024 bytes.

The next candidate is 192 KiB. The script verifies its expected SHA256, moves it from staging into the same fixture's archive directory, copies it into an isolated restore directory, and verifies the restored bytes. Only then does the valid case remove its oldest synthetic file.

StageArchive / stagingRestoreTotal
Seven existing copies944 KiB0944 KiB
New candidate written944 + 192 KiB01,136 KiB
Restore checked; before removal1,136 KiB192 KiB1,328 KiB
Oldest 128 KiB copy removed1,008 KiB192 KiB1,200 KiB

These are sums of actual logical file lengths in the fixture. Keeping seven files did not keep the total fixed at 944 KiB: the incoming copy is larger than the outgoing one. The final seven archive copies occupy 1,008 KiB.

A budget that passes after removal but fails at the peak

For arithmetic only, assume a 1,500 KiB total budget and a 256 KiB operating reserve. Neither is a measured server limit. After rotation, the archive plus retained restore copy and reserve is 1,008 + 192 + 256 = 1,456 KiB, which fits that budget. At the pre-removal peak it is 1,136 + 192 + 256 = 1,584 KiB, which exceeds it by 84 KiB.

Starting from the existing 944 KiB, this plan needs another 640 KiB for the candidate, restore copy and reserve. That headroom is distinct from the final retained archive size. We did not fill a disk or provoke a write failure; the budget check is a comparison against an assumed limit.

What if the new copy is incomplete?

A second independent fixture writes only the first 64 KiB of the expected 192 KiB candidate. Its hash fails validation. The script stops promotion and removal, leaving all seven original files byte-for-byte unchanged. The partial candidate remains in staging for inspection, so this case consumes 944 + 64 = 1,008 KiB in logical file data.

This negative control makes an important condition visible: an attempted backup is not a validated replacement. Automatically deleting the oldest copy before checking the new one would spend an existing recovery point on a candidate that might be unusable. When the peak does not fit, revise the capacity or workflow explicitly rather than treating pre-deletion as a harmless arithmetic shortcut.

Our SHA256 readback establishes only that the fixture's bytes match independently generated expected bytes. It does not establish application consistency, database recovery, access to encryption keys or the ability to rebuild a server. For an example of those different checks, see our SQLite recovery-point and consumer validation.

“Seven” needs a precise definition

Seven latest snapshots, one snapshot from each of seven days, and all snapshots younger than seven days are different policies. Multiple runs per day and missed days change which recovery points remain. Decide the dates and states you must be able to recover, including failures and skipped runs; a count alone does not promise a maximum age or seven successful daily backups.

Real backup tools also define grouping and selection rules. Restic's retention documentation distinguishes --keep-last from --keep-daily; the latter selects the latest snapshot for each of the last days that actually have snapshots. Filters and groups matter. Read and preview the policy against the intended repository and backup set before making a change.

Full-copy sums do not predict a deduplicating repository

The files in our drill are independent full copies. There is no compression, shared chunk, incremental chain or hard link. You cannot multiply their measured bytes into a reliable estimate for Restic, Borg, filesystem snapshots or a compressed database backup. Measure representative stored growth and maintenance behavior in the actual format instead.

Selection and space reclamation can also be separate steps. Restic documents forget for removing snapshot references and prune for removing data no longer referenced. Borg's prune documentation states that repository disk space is not freed until borg compact runs, and recommends inspecting a dry run. These are tool-specific semantics, not commands our script executes. Maintenance may need its own time and workspace.

A logical file disappearing is not always an immediate free-space increase either: our deleted-open file drill demonstrates one Linux reason. Keep archive totals, allocated storage, quotas and filesystem free space distinct.

Repeat the isolated experiment

python3 backup_retention_demo.py --out ./retention-drill-output

Use your Python 3 command, such as python on some systems. The script needs only the standard library and at least 64 MiB of free workspace. It creates a new uniquely named directory and uses only a few MiB of synthetic file data. It accepts no existing backup repository or application path. Its only deletion is the oldest binary file it created inside the successful fixture; the failed case retains all its files.

Read before, after, stages and planning in the printed result-file path. Both cases passed their expectations, including rejection of the truncated candidate. The overall pass is not approval of any real retention policy.

A worksheet for your own backup job

  1. Define the required recovery points and how you will validate a replacement.
  2. Inventory actual retained sizes, timestamps and the volume holding each copy. Preserve errors and missing observations.
  3. Draw the operation order: candidate creation, promotion, restore rehearsal and removal. Count simultaneous copies at each stage.
  4. Estimate the next copy and temporary workspace from measured history, allowing for growth. State the reserve separately.
  5. Check the maximum per-volume total, not only the final total. If it does not fit, revise the plan before scheduling.
  6. Preview the exact retention selection, validate recovery, and keep the result and remaining work in the job's run record.

Copies on one server or volume do not protect against loss of that server or volume. This drill is a local space calculation, not an offsite recovery design, restore-time measurement, real disk-full recovery test or production cleanup procedure.

Sources

Documentation checked November 7, 2026 (Asia/Shanghai). All byte measurements above come from our own synthetic full-copy fixture; no Restic or Borg repository was opened or modified.

Keep several plans in one report

The Offline Budget Report Kit candidate compares explicit memory allowances and storage peaks per volume. See its sample outputs and limits → Preview only; not currently for sale. The browser calculator and starter pack remain free.