---
title: "Restic repository on Backblaze B2 keeps growing"
description: "B2 cannot disable versioning and the recommended lifecycle rule does not keep pace with restic. Backblaze confirmed the gap when we escalated it."
source: "https://wardio.net/guides/restic-backblaze-storage-growth/"
---

**Backups**

# A restic repository on Backblaze B2 keeps growing because of versioning

Your backup is 400 GB and your bucket is over a terabyte. Nothing is broken and the recommended lifecycle rule is on, yet the gap keeps widening.

By David Kabel · Updated 2026-09-23 · 7 min read

**The short answer**

Backblaze B2 buckets are always versioned, and you cannot turn versioning off. restic's documentation recommends the S3-compatible API for B2. When restic prunes or repacks through that API, each delete becomes a hide marker and B2 keeps the old version. The *Keep only the last version of the file* lifecycle rule is supposed to clear those, but it does not keep pace with how restic rewrites pack files. Backblaze support confirmed the gap when we escalated it. Their remedy is an external cleanup that lists versions, keeps the current one and deletes the rest.

## Versioning and pruning open the gap

1.  **B2 buckets are always versioned, with no off switch**: Versioning is part of the platform, not a setting, and Backblaze support confirmed there is no option to disable it. restic's documentation recommends the S3-compatible API for B2. Through that API, every delete restic issues becomes a hide marker, and B2 keeps the previous version behind it. restic's native b2: backend behaves differently. With a key that has deleteFiles, it deletes the versions permanently.
2.  **restic keeps deleting and replacing files**: Pruning repacks data. restic removes old pack files and writes new ones. On a normal filesystem that reclaims space. On B2 it leaves two objects where there was one.
3.  **The recommended lifecycle rule does not keep pace**: restic's own documentation and most write-ups point at Keep only the last version of the file. The rule helps, but it does not match restic's repack pattern and leaves hidden versions behind.
4.  **The repository grows while the backup does not**: You see a bucket several times the size restic reports. The backup itself is fine. The extra storage on the bill is versions nobody can use.

## Backblaze's answer

We ran into this across several client repositories and escalated it. Backblaze's Technical Support Engineering team replied that the lifecycle rule *does not always match restic's cleanup/repack behavior exactly, especially when restic deletes or replaces pack files in ways that leave hidden versions behind.*

They did not suggest a different lifecycle rule. They recommended letting restic manage its repository normally and then running a separate cleanup process that removes the old hidden versions afterwards. They also agreed that their own restic guide does not cover this and passed it to their documentation team.

In our client repositories the buckets have come out at roughly two to three times the expected repository size. We observed that figure across several accounts. It is not a Backblaze measurement, so treat it as an order of magnitude and not a constant.

## One suggestion to ignore

The first advice we received was to set `daysFromUploadingToHiding` to 1. Do not do this on a restic bucket. It hides every file including the current version about 24 to 48 hours after upload, so restic can no longer read its own pack files and restores fail. Support corrected it in their next message. The setting looks harmless and only fails on the day you need a restore, so leave that field unset.

## Run a version cleanup instead

Leave *Keep only the last version of the file* switched on, because it does remove some of the accumulation. Then run a cleanup that lists object versions, keeps every current object and deletes non-current ones hidden longer ago than a cutoff. Backblaze suggested this approach. On a test bucket, such a cleanup cut 129 MB of stored versions back to the 30 MB restic was using, and `restic check --read-data` passed afterwards.

Whether that cleanup helps or hurts depends on where it runs and how far back it deletes.

**Run it off the backed-up server.** Deleting object versions needs delete permissions. If you restricted your backup key so a compromised server cannot destroy its own history, a cleanup on that server gives back the permission you removed. Put it on a separate administrative machine the backed-up server cannot reach.

**Retention window.** On S3-compatible storage `PutObject` is the overwrite, and there is no separate permission to withhold. That leaves old versions as the only protection against an attacker who holds the server's credentials and overwrites objects. Deleting them reclaims space and removes that protection. Size the retention window against how long you would take to *notice* a compromise, not against your storage bill. If you would take a month to spot the problem, a week of history will not save you.

## Regulated write-once retention needs more than restic

This setup alone does not meet a regulation that requires genuine write-once retention. restic does run on a bucket with Object Lock, because its deletes become hide markers and leave locked versions in place. It cannot set or extend locks, though. Each file is protected only for a fixed period after upload, while current snapshots still depend on older pack files whose locks have expired. [The Object Lock guide](/guides/restic-b2-object-lock/) covers what that combination does and does not protect against. An earlier version of this page said restic stops working under Object Lock. That was wrong, and this version corrects it.

## Gotchas

-   **restic's numbers are not the bill.** After five backup and prune cycles on a versioned test bucket with no expiry rule, `restic stats --mode raw-data` reported 27.2 MiB while the bucket held 129 MB in 60 versions, 4.3 times its 30 MB of current objects. A single prune had already doubled it. Measure with `b2 bucket get --show-size`, which counts hidden versions, not with restic.
-   **Age versions from when they were hidden, not uploaded.** A non-current version's own timestamp is its upload time. With a 30 second cutoff, a cleanup that used it picked two packs that prune had hidden 12 seconds earlier, because they were uploaded 47 seconds before that. Take the age from the next newer version or hide marker for the same name, which is how Backblaze's lifecycle rules count. The cleanup that did this kept both packs.
-   **Locked versions refuse deletion.** On a compliance-mode test bucket, MinIO refused the cleanup on all 12 hidden versions with "Object is WORM protected", an HTTP 400. Backblaze documents 401 access\_denied for the same case. A script that stops at the first error never reaches the rest. Log the refusal, skip the version, and let a later run delete it once the lock expires.
-   **A backup key with no delete at all leaves stale locks.** With a key limited to list, read and write, every restic run printed `error while unlocking` with Access Denied and left its lock file behind. One `forget` with that key left an exclusive lock that made every later backup exit 11 until the admin host ran `restic unlock --remove-all`. Backblaze documents that `writeFiles` covers deleting by name, so a B2 key without `deleteFiles` can still hide its locks. On other S3 storage allow `s3:DeleteObject` under `locks/` only and explicitly deny `s3:DeleteObjectVersion`. On MinIO, leaving the version delete ungranted was not enough.

**How this was tested.** On 23 September 2026 we ran restic 0.19.1 against MinIO RELEASE.2025-09-07T16-13-09Z in Docker on an Ubuntu 24.04 host, as an S3-compatible stand-in for B2, with AWS CLI 1.46.1 and mc RELEASE.2025-08-13T08-35-41Z. The runs covered repeated backup and prune cycles on a versioned bucket, a version cleanup script in both age modes followed by `restic check --read-data`, a compliance-mode bucket, and restricted keys. We tested nothing against a live Backblaze B2 account. B2's always-on versioning, how the *Keep only the last version* rule keeps pace and what support told us rest on Backblaze's documentation and our correspondence. The two to three times figure comes from client accounts. We configured MinIO lifecycle expiry but did not observe it, because its shortest period is one day.

## Sources

1.  [Preparing a new repository: Backblaze B2](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html), restic documentation
2.  [B2 backend source, Remove](https://github.com/restic/restic/blob/master/internal/backend/b2/b2.go), restic
3.  [Lifecycle Rules](https://www.backblaze.com/docs/cloud-storage-lifecycle-rules), Backblaze B2 documentation
4.  [S3-Compatible App Keys](https://www.backblaze.com/docs/cloud-storage-s3-compatible-app-keys), Backblaze
5.  [b2\_delete\_file\_version](https://www.backblaze.com/apidocs/b2-delete-file-version), Backblaze B2 Native API
6.  [B2 command-line tool documentation](https://b2-command-line-tool.readthedocs.io/en/master/), Backblaze, version 5.0.0

## Questions

### Can I turn off versioning on a Backblaze B2 bucket?

No. B2 buckets are always versioned and no setting disables it. Backblaze support confirmed this to us. Deleting a file by name creates a hide marker and leaves the data in place, which is the reason lifecycle rules exist at all.

### Does the "Keep only the last version of the file" lifecycle rule fix restic storage growth?

Only partly. Backblaze's Technical Support Engineering team confirmed that the rule does not always match restic's cleanup and repack behaviour. The mismatch shows most where restic deletes or replaces pack files in ways that leave hidden versions behind. They recommend an external cleanup process, not a different lifecycle rule.

### Should I set daysFromUploadingToHiding to 1 on a restic bucket?

No. That hides every file including the current version roughly 24 to 48 hours after upload, so restic can no longer read its own pack files and restores break. Leave daysFromUploadingToHiding unset on a restic bucket. Only daysFromHidingToDeleting is safe to set.

### Where should the cleanup script run?

Not on the backed-up server. Deleting object versions needs delete permissions, and an append-only backup design keeps that permission off the protected machine. Run the cleanup from a separate administrative host that the backed-up server cannot reach.

**Paying for versions nobody can restore from?**

The free review compares what your backup costs with what it protects. [The wider backup guide](/guides/backups-that-restore/) covers the rest.

[Free server review](/contact/)
