{"id":20384941,"url":"https://github.com/d-e-s-o/btrfs-backup","last_synced_at":"2026-05-28T16:01:14.508Z","repository":{"id":68639623,"uuid":"598941339","full_name":"d-e-s-o/btrfs-backup","owner":"d-e-s-o","description":"A program for backup \u0026 restoration of btrfs subvolumes.","archived":false,"fork":false,"pushed_at":"2026-03-20T13:42:08.000Z","size":277,"stargazers_count":12,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-21T04:57:13.724Z","etag":null,"topics":["backup","btrfs","btrfs-snapshots","btrfs-subvolume","incremental-backups","rust","rust-lang"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/d-e-s-o.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-02-08T05:36:10.000Z","updated_at":"2026-03-20T13:42:13.000Z","dependencies_parsed_at":null,"dependency_job_id":"48a5ff08-a2e0-46b3-99aa-2256f71f27d3","html_url":"https://github.com/d-e-s-o/btrfs-backup","commit_stats":{"total_commits":79,"total_committers":1,"mean_commits":79.0,"dds":0.0,"last_synced_commit":"02aea34ba9d32e7d18e151d1cf6a10c4c1d787d6"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/d-e-s-o/btrfs-backup","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d-e-s-o%2Fbtrfs-backup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d-e-s-o%2Fbtrfs-backup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d-e-s-o%2Fbtrfs-backup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d-e-s-o%2Fbtrfs-backup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/d-e-s-o","download_url":"https://codeload.github.com/d-e-s-o/btrfs-backup/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d-e-s-o%2Fbtrfs-backup/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33615490,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-28T02:00:06.440Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backup","btrfs","btrfs-snapshots","btrfs-subvolume","incremental-backups","rust","rust-lang"],"created_at":"2024-11-15T02:30:47.061Z","updated_at":"2026-05-28T16:01:14.454Z","avatar_url":"https://github.com/d-e-s-o.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![pipeline](https://github.com/d-e-s-o/btrfs-backup/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/d-e-s-o/btrfs-backup/actions/workflows/test.yml)\n[![crates.io](https://img.shields.io/crates/v/btrfs-backup.svg)](https://crates.io/crates/btrfs-backup)\n\nbtrfs-backup\n============\n\n- [Changelog](CHANGELOG.md)\n\n**btrfs-backup** is a program that can be used to backup data from one\nor multiple btrfs file systems. It relies on the btrfs(8) utility\nprogram to perform its job and provides a very simple interface for\nquick btrfs snapshot creation and transferal.\n\nAs for the btrfs file system itself, the unit of backup is a subvolume.\nCreation of snapshots for subvolumes is performed on an on demand basis,\nthat is, only if new data is detected to be available on the respective\nsubvolume a new snapshot is taken. Transfer of data can happen\nincrementally, i.e., only changes over the most recent snapshot state\nwill have to be sent.\n\nThe program reasons in terms of repositories. A repository is a\ndirectory which is used to contain the newly created as well as already\navailable snapshots.\n\nIn terms of backup there are two repositories involved: a source\nrepository and a destination repository. These repositories are kept in\nsync by performing an incremental transfer of the files of a snapshot\nfrom the source to the destination. On the destination repository, the\nsnapshot will subsequently be remanifested or stored in a file.\n\n\nUsage\n-----\n\nLet's say you have two subvolumes that you would like to back up to\nsome external HDD mounted at `/mnt/backup`:\n```sh\n# Mount some backup drive.\n$ mount /mnt/backup/\n# Create a fake hierarchy of btrfs subvolumes for illustration purposes.\n$ mkdir /.btrfs-root/\n$ mkdir /.btrfs-root/subdir\n$ btrfs subvolume create /.btrfs-root/subvol1\n$ btrfs subvolume create /.btrfs-root/subdir/subvol2\n```\n\n```\n/.btrfs-root/\n├── subdir\n│   └── subvol2\n└── subvol1\n```\n\n\n### Backup\nIn this setup, backup can be as simple as:\n```sh\n$ btrfs-backup backup \\\n    /.btrfs-root/subvol1 \\\n    /.btrfs-root/subdir/subvol2 \\\n    --destination /mnt/backup/\n```\n\nThis command results in the following backup snapshots:\n```\n/mnt/backup/\n├── \u003chostname\u003e_.btrfs-root-subdir-subvol2_2023-02-20_11:14:35_\n└── \u003chostname\u003e_.btrfs-root-subvol1_2023-02-20:11:14:35_\n```\n\nThe way backups work on a btrfs file system, a read-only snapshot of the\nsubvolume to back up is created on the source file system and then sent\nover to the destination file system. Shown above are the snapshots on\nthe destination file system. Because we did not provide the `--source`\nargument to the command, snapshots on the source file system are\nco-located with the actual subvolume in question (that is, they reside\nin the same parent directory):\n```\n/.btrfs-root/\n├── \u003chostname\u003e_.btrfs-root-subvol1_2023-02-20_11:14:35_\n├── subdir\n│   ├── \u003chostname\u003e_.btrfs-root-subdir-subvol2_2023-02-20_11:14:35_\n│   └── subvol2\n└── subvol1\n```\n\nIf you want to have snapshots centrally managed, provide the `--source`\nflag with a path to a directory on the btrfs file system on which the\nsubvolumes to back up are located:\n\n```sh\n# Create central snapshot location.\n$ mkdir /snapshots\n$ btrfs-backup backup \\\n    /.btrfs-root/subvol1 \\\n    /.btrfs-root/subdir/subvol2 \\\n    --source /snapshots \\\n    --destination /mnt/backup/\n```\n\nNow instead of the snapshots residing next to the subvolumes:\n```\n/.btrfs-root/\n├── subdir\n│   └── subvol2\n└── subvol1\n```\n\nThey are located in a single directory:\n```\n/snapshots/\n├── \u003chostname\u003e_.btrfs-root-subdir-subvol2_2023-02-20_11:14:35_\n└── \u003chostname\u003e_.btrfs-root-subvol1_2023-02-20_11:14:35_\n```\n\n\n### Restore\nSubvolumes can be restored in a similar fashion, using\n**btrfs-backup**'s `restore` sub-command:\n```sh\n# Let's say all our source data is gone and only /mnt/backup still\n# available.\n$ rm -rf /.btrfs-root\n$ btrfs-backup restore \\\n    /.btrfs-root/subvol1 \\\n    /.btrfs-root/subdir/subvol2 \\\n    --source /mnt/backup/\n```\n\nEssentially, we now use `/mnt/backup` as the source repository and get\nback our original subvolume state along with co-located snapshots (it\nworks analogous with centrally managed snapshots if you provide the\n`--destination` argument):\n```\n/.btrfs-root/\n├── \u003chostname\u003e_.btrfs-root-subvol1_2023-02-20_11:14:35_\n├── subdir\n│   ├── \u003chostname\u003e_.btrfs-root-subdir-subvol2_2023-02-20_11:14:35_\n│   └── subvol2\n└── subvol1\n```\n\n\n### Purge\n**btrfs-backup** is able to identify and delete no longer used snapshots\nvia the `purge` sub-command. This sub-command accepts the `--keep-for`\nargument that understands a duration specification such as `2d` (two\ndays), `1w` (one week), `5m` (five months), `1y` (one year) and will\ndelete snapshots older than that.\n\nFor example given the following state:\n```\n/.btrfs-root/\n├── \u003chostname\u003e_.btrfs-root-subvol1_2023-01-31_19:56:07_\n├── \u003chostname\u003e_.btrfs-root-subvol1_2023-02-10_09:23:11_\n├── \u003chostname\u003e_.btrfs-root-subvol1_2023-02-20_11:14:35_\n├── subdir\n│   ├── \u003chostname\u003e_.btrfs-root-subdir-subvol2_2023-01-31_19:56:07_\n│   ├── \u003chostname\u003e_.btrfs-root-subdir-subvol2_2023-02-10_09:23:11_\n│   ├── \u003chostname\u003e_.btrfs-root-subdir-subvol2_2023-02-20_11:14:35_\n│   └── subvol2\n└── subvol1\n```\n\nThe following command:\n```sh\n$ date\n\u003e Mo 20. Feb 11:15:53 PST 2023\n# Delete all snapshots older than two weeks.\n$ btrfs-backup purge \\\n    /.btrfs-root/subvol1 \\\n    /.btrfs-root/subdir/subvol2 \\\n    --destination /mnt/backup/ \\\n    --keep-for 2w\n```\nwill result in the snapshots from `2023-01-31` to be removed because\nthey are more than two weeks old:\n```\n/.btrfs-root/\n├── \u003chostname\u003e_.btrfs-root-subvol1_2023-02-10_09:23:11_\n├── \u003chostname\u003e_.btrfs-root-subvol1_2023-02-20_11:14:35_\n├── subdir\n│   ├── \u003chostname\u003e_.btrfs-root-subdir-subvol2_2023-02-10_09:23:11_\n│   ├── \u003chostname\u003e_.btrfs-root-subdir-subvol2_2023-02-20_11:14:35_\n│   └── subvol2\n└── subvol1\n```\n\nPlease note that the original backed up subvolume will never be deleted\n-- only its snapshots will ever be \"purged\". On top of that, the most\nrecent snapshot is also always preserved to aid with *incremental*\nbackups in the future.\n\n\n### Remote Execution\nIn many cases it is a requirement to backup a subvolume to a remote host\n(or restore a subvolume from it). Mounting a remote btrfs file system\nlocally by means of, for instance, SSHFS will not provide the ability to\nuse btrfs specific tools on it.\nTo that end, commands can be run on the remote host directly (provided\nit offers an interface for command execution from the outside and that\nis has the required btrfs tool suite installed). A typical example for\nremote command execution is SSH. Using **btrfs-backup** on a remote host\nby means of an SSH connection can be achieved with the\n`--remote-command` argument, which can be provided to the `backup`,\n`restore`, as well as `purge` sub-commands. E.g.,\n\n```\n$ btrfs-backup backup --remote-command='ssh server'\n$ btrfs-backup backup \\\n    /.btrfs-root/subvol1 \\\n    /.btrfs-root/subdir/subvol2 \\\n    --destination /mnt/backup/ \\\n    --remote-command='ssh server'\n```\n\nThis command will transfer snapshots over an SSH connection to `server`.\nThey will be stored inside `/mnt/backup` on the remote system.\n\n\n### Snapshot Tagging\nSnapshots can be \"tagged\" with a more or less arbitrary string, which\nwill be contained in the snapshot name. Doing so is enabled by means of\nthe `--tag` argument to various sub-commands.\n\nWhen a `purge` is performed, only snapshots of the provided tag will be\naffected and all others will be left untouched. That can be useful when\nsubvolumes are backed up to multiple backups at different frequencies,\nas it can help ensure that relevant snapshots are not removed\nautomatically to preserve the incremental nature of future backups.\n\nOn top of that, tags also serve an informational purpose: because the\ntag is contained in the snapshot's name, it can be used to easily\nidentify when a subvolume has been backed up to a certain backup\nlocation last, for example.\n\nPlease refer to the help text (`--help`) for additional details.\n\n\nInstallation\n------------\n\n**btrfs-backup** is written in Rust and requires the Cargo package\nmanager to be built. It can be installed using `cargo install\nbtrfs-backup`. The program requires [`btrfs-progs`][btrfs-progs] to be\ninstalled and its `btrfs` binary to be discoverable via the `PATH`\nenvironment variable.\n\n\nStatus\n------\n\nThe program supports backup and restoration of subvolumes on a single\nsystem as well as to/from a remote one (e.g., over an `ssh` connection).\nIt also can automatically clean stale snapshots. As such, it is fully\nusable for backup needs.\n\nCompared to the [original][btrfs-backup-py] Python version of the\nprogram, the snapshot naming scheme has changed and a few bugs have been\nfixed. Support for backups to files is not yet present (and may not ever\nbe added, as it was considered a fringe feature that was not used\nregularly).\n\n[btrfs-backup-py]: https://github.com/d-e-s-o/btrfs-backup-python/tree/main/btrfs-backup\n[btrfs-progs]: https://github.com/kdave/btrfs-progs\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd-e-s-o%2Fbtrfs-backup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fd-e-s-o%2Fbtrfs-backup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd-e-s-o%2Fbtrfs-backup/lists"}