-
0.9.6-beta.7
Pre-ReleaseCI / unit (8.2) (push) Has been cancelledCI / unit (8.3) (push) Has been cancelledCI / unit (8.4) (push) Has been cancelledCI / psalm (push) Has been cancelledCI / integration (mariadb, 32) (push) Has been cancelledCI / integration (mariadb, 33) (push) Has been cancelledCI / integration (mariadb, 34) (push) Has been cancelledCI / integration (mariadb, 35) (push) Has been cancelledCI / integration (pgsql, 32) (push) Has been cancelledCI / integration (pgsql, 33) (push) Has been cancelledCI / integration (pgsql, 34) (push) Has been cancelledCI / integration (pgsql, 35) (push) Has been cancelledCI / integration (sqlite, 32) (push) Has been cancelledCI / integration (sqlite, 33) (push) Has been cancelledCI / integration (sqlite, 34) (push) Has been cancelledCI / integration (sqlite, 35) (push) Has been cancelledCI / integration-targets (push) Has been cancelledCI / integration-user (32) (push) Has been cancelledCI / integration-user (33) (push) Has been cancelledCI / integration-user (34) (push) Has been cancelledCI / integration-user (35) (push) Has been cancelledCI / integration-full-restore (push) Has been cancelledreleased this
2026-10-14 13:21:02 +02:00 | 165 commits to main since this releaseBugfix release for SMB locations, with
occ backup:cancelto stop a backup that does not get
anywhere. Tested on a production instance: a first full backup of 151,021 files (807 GiB) to OVH
S3 completed, and a backup to a Hetzner Storage Box over SMB that had slowed to 12 GiB in 35
hours ran at about 5.6 MiB/s after the update, while the S3 backup was still reading.Added
- The list of backup runs (web interface and
occ backup:status) shows the total size of each
backup next to what it uploaded: an incremental backup of 1 TB that uploads 800 MB now shows
both.occ backup:statusshows sizes in GiB where that reads better than MiB. occ backup:cancel <run>stops a running backup;occ backup:statusshows the run numbers.
No new step of the run starts, the step in progress finishes (usually within a minute), then
the process working on the run (occ backup:runor cron) stops. What it already stored is
removed by the next cleanup. A backup started by an earlier version is stopped as well: after
two minutes it is marked cancelled while it works, and its process stops at the end of the
step.
Fixed
- Backups to SMB locations, and to other slow locations with many packs, slowed to a crawl: each
30-second step opened the location again, and reading the list of index files took longer
than the step itself. Each step then stored a single 4 MiB pack, which made the list longer
still. A first full backup of 0.8 TB to a Hetzner Storage Box over SMB managed 12 GiB in 35
hours.occ backup:runand system cron now open the location once per run, opening no longer
counts towards the step's time, and SMB folders are listed in one request instead of one per
file. A backup to an SMB location that is not getting anywhere keeps running in its old
process after the update: update first, then stop it withocc backup:cancel <run>and start
it again. The new backup reuses the packs the old one stored.
Downloads
- The list of backup runs (web interface and
-
0.9.5-beta.6
Pre-ReleaseCI / unit (8.2) (push) Has been cancelledCI / unit (8.3) (push) Has been cancelledCI / unit (8.4) (push) Has been cancelledCI / psalm (push) Has been cancelledCI / integration (mariadb, 32) (push) Has been cancelledCI / integration (mariadb, 33) (push) Has been cancelledCI / integration (mariadb, 34) (push) Has been cancelledCI / integration (mariadb, 35) (push) Has been cancelledCI / integration (pgsql, 32) (push) Has been cancelledCI / integration (pgsql, 33) (push) Has been cancelledCI / integration (pgsql, 34) (push) Has been cancelledCI / integration (pgsql, 35) (push) Has been cancelledCI / integration (sqlite, 32) (push) Has been cancelledCI / integration (sqlite, 33) (push) Has been cancelledCI / integration (sqlite, 34) (push) Has been cancelledCI / integration (sqlite, 35) (push) Has been cancelledCI / integration-targets (push) Has been cancelledCI / integration-user (32) (push) Has been cancelledCI / integration-user (33) (push) Has been cancelledCI / integration-user (34) (push) Has been cancelledCI / integration-user (35) (push) Has been cancelledCI / integration-full-restore (push) Has been cancelledreleased this
2026-10-12 15:06:12 +02:00 | 170 commits to main since this releaseBugfix release for SFTP locations and large repositories. Tested on a production instance with a
1 TB repository on a Hetzner Storage Box over SFTP: a check in 5.5 minutes, a deep check of all
316,529 blobs (815 GiB) in 11 hours, and an incremental backup in under 8 minutes.Added
- Progress of a running backup in the web interface and
occ backup:status, e.g.
"running (files) 68%". The total is the size of the previous snapshot; for a first backup it
is estimated from Nextcloud's file cache (users' files, versions and trash) and shown as
"~68%". - Edit a backup location (web interface and
occ backup:target:edit): change the password, host,
folder, connection type or name without losing its history. Before this the only option was a
new location, which starts an empty repository and, with a retention lock at the provider,
keeps paying for the old one. The new settings are only saved when they lead to the same
repository; stored passwords are never sent to the browser, and an empty password field keeps
the stored one. Administrators are notified of the change. occ backup:verifyreports how far it is every 30 seconds, andocc backup:statusshows the
progress of a running check and how the last check of each location ended. On a large
repository a check takes hours, a deep one days.
Changed
- Checking and opening a large repository over SFTP is much faster: the index files (one per
pack, 27,547 for 1 TB) are downloaded 32 at a time instead of one after the other, 114 instead
of 6 files per second to a Hetzner Storage Box (about 4 minutes instead of 77 for 1 TB). A check
of a repository with more than 256 packs also lists the pack folders (256 requests) instead of
asking for every pack. - App store listing: the author's e-mail address is shown.
- App store listing: the homepage link points to the GitHub repository instead of back to the
app store page itself. - The notification for a location without a successful backup read "No successful backup to …
since never" when there had never been one; it now reads "No successful backup to … yet".
Fixed
- 0.9.4 could not open a repository at the root of an SFTP location (empty path): its faster
SFTP reads sent their first request before phpseclib had opened the SFTP channel, which only
happens on the first SFTP call after login. Every backup then failed with "No repository at
this location". The channel is now opened first. - A check (
occ backup:verify) did not renew its hold on the location while it downloaded the
index; on a large repository that takes longer than the hold lasts, so a weekly cleanup could
have started during the check. - A long first backup could end as failed although its snapshot was complete: when its final
step took longer than the step's lease (150 s withocc backup:run), the background job took
the run over, finished it a second time and failed on the snapshot it had already recorded,
overwriting the result. The lease now lasts at least 15 minutes, a step writes the run only if
no other process wrote it since the step loaded it (in one database statement), and recording
a snapshot that is already recorded is no longer an error. occ backup:verifyon a large repository failed with "SFTP connection failed while opening
snapshots/…" or "Not found: snapshots/…". A Hetzner Storage Box drops an SFTP connection that
carried a lot of data (some 40 MB) and then stayed quiet for a few minutes, and the check went
quiet after downloading the index: it refreshed the local index cache, first in 29 minutes (a
pass over all blobs for every pack: 27,547 packs, 400,000 blobs for 1 TB), then still in more
than 6 minutes (a database transaction per pack on PostgreSQL). Nextcloud's SFTP storage keeps
using a dropped connection, on which every file looks missing. Now:- an SFTP connection that was not used for a minute is checked first, and one that turns out
to be dead after a failed request is replaced, once per request; uploads, moves and deletes
are only checked first, never repeated; - the index cache is written in one transaction (27,547 packs in 11 seconds on a test server,
against about a minute row by row); - after a check the cache holds the index files as they are: before, a blob that was in two
packs was only cached for one of them.
- an SFTP connection that was not used for a minute is checked first, and one that turns out
Package
ng_backup-0.9.5.tar.gzis the signed app store package (code-signed with the Nextcloud certificate forng_backup);.sigis its app store signature.Downloads
- Progress of a running backup in the web interface and
-
v0.9.4-beta.5 — bugfix release
Pre-ReleaseCI / unit (8.2) (push) Has been cancelledCI / unit (8.3) (push) Has been cancelledCI / unit (8.4) (push) Has been cancelledCI / psalm (push) Has been cancelledCI / integration (mariadb, 32) (push) Has been cancelledCI / integration (mariadb, 33) (push) Has been cancelledCI / integration (mariadb, 34) (push) Has been cancelledCI / integration (mariadb, 35) (push) Has been cancelledCI / integration (pgsql, 32) (push) Has been cancelledCI / integration (pgsql, 33) (push) Has been cancelledCI / integration (pgsql, 34) (push) Has been cancelledCI / integration (pgsql, 35) (push) Has been cancelledCI / integration (sqlite, 32) (push) Has been cancelledCI / integration (sqlite, 33) (push) Has been cancelledCI / integration (sqlite, 34) (push) Has been cancelledCI / integration (sqlite, 35) (push) Has been cancelledCI / integration-targets (push) Has been cancelledCI / integration-user (32) (push) Has been cancelledCI / integration-user (33) (push) Has been cancelledCI / integration-user (34) (push) Has been cancelledCI / integration-user (35) (push) Has been cancelledCI / integration-full-restore (push) Has been cancelledreleased this
2026-10-09 12:05:48 +02:00 | 193 commits to main since this releaseBugfix release: faster restores.
Fixed
- Restores and
occ backup:verify --deepfetched every blob with its own request, so on a
remote location they ran far below the speed of the connection. The blobs of a pack are now
read from one open stream, in the order they were written. Restoring 86 MB in 202 files from a
Hetzner Storage Box over SMB went from 0.78 MB/s to 4.2 MB/s, the speed of reading the packs
as plain files over that connection. - Reading from an SFTP location waited a full round trip for every 256 KiB, whatever the line
speed. Reads now keep up to 8 requests in flight. Restoring 1.97 GB in 500 files from a Hetzner
Storage Box (47 ms away) took 694 s before the fix above, 499 s with it and 142 s with both
(2.8 → 3.9 → 13.9 MB/s); a full 51 GB restore ran at 13.0 MB/s. When a server error
interrupts such a read, it goes on from the same position with Nextcloud's own SFTP stream;
after three failing files in a row, or on a Nextcloud whose SFTP library lacks what this needs,
only Nextcloud's own stream is used. - README: a WebDAV location on a slow upload needs a higher
davstorage.request_timeout.
Package
ng_backup-0.9.4.tar.gzis the signed app store package (code-signed with the Nextcloud certificate forng_backup);.sigis its app store signature.Downloads
- Restores and
-
v0.9.3-beta.4 — bugfix release
Pre-ReleaseCI / unit (8.2) (push) Has been cancelledCI / unit (8.3) (push) Has been cancelledCI / unit (8.4) (push) Has been cancelledCI / psalm (push) Has been cancelledCI / integration (mariadb, 32) (push) Has been cancelledCI / integration (mariadb, 33) (push) Has been cancelledCI / integration (mariadb, 34) (push) Has been cancelledCI / integration (mariadb, 35) (push) Has been cancelledCI / integration (pgsql, 32) (push) Has been cancelledCI / integration (pgsql, 33) (push) Has been cancelledCI / integration (pgsql, 34) (push) Has been cancelledCI / integration (pgsql, 35) (push) Has been cancelledCI / integration (sqlite, 32) (push) Has been cancelledCI / integration (sqlite, 33) (push) Has been cancelledCI / integration (sqlite, 34) (push) Has been cancelledCI / integration (sqlite, 35) (push) Has been cancelledCI / integration-targets (push) Has been cancelledCI / integration-user (32) (push) Has been cancelledCI / integration-user (33) (push) Has been cancelledCI / integration-user (34) (push) Has been cancelledCI / integration-user (35) (push) Has been cancelledCI / integration-full-restore (push) Has been cancelledreleased this
2026-10-08 21:18:08 +02:00 | 201 commits to main since this releaseBugfix release.
Fixed
- A backup failed with "cannot execute INSERT in a read-only transaction" on PostgreSQL as soon
as the database dump filled a whole pack (32 MiB): the pack's index cache row was written
inside the read-only dump transaction. On other databases that row was rolled back silently. - Backups to a remote location slowed down as the repository grew: every backup step listed the
repository's index with a round trip per file. Over SFTP to a Hetzner Storage Box a 60 GiB
repository already lost a large part of each step to it; backing up continuously
(occ backup:run) went from 45 KiB/s to 5.8 MB/s with the fix.
Package
ng_backup-0.9.3.tar.gzis the signed app store package (code-signed with the Nextcloud certificate forng_backup);.sigis its app store signature.Downloads
- A backup failed with "cannot execute INSERT in a read-only transaction" on PostgreSQL as soon
-
v0.9.2-beta.3 — bugfix release
Pre-ReleaseCI / unit (8.2) (push) Has been cancelledCI / unit (8.3) (push) Has been cancelledCI / unit (8.4) (push) Has been cancelledCI / psalm (push) Has been cancelledCI / integration (mariadb, 32) (push) Has been cancelledCI / integration (mariadb, 33) (push) Has been cancelledCI / integration (mariadb, 34) (push) Has been cancelledCI / integration (mariadb, 35) (push) Has been cancelledCI / integration (pgsql, 32) (push) Has been cancelledCI / integration (pgsql, 33) (push) Has been cancelledCI / integration (pgsql, 34) (push) Has been cancelledCI / integration (pgsql, 35) (push) Has been cancelledCI / integration (sqlite, 32) (push) Has been cancelledCI / integration (sqlite, 33) (push) Has been cancelledCI / integration (sqlite, 34) (push) Has been cancelledCI / integration (sqlite, 35) (push) Has been cancelledCI / integration-targets (push) Has been cancelledCI / integration-user (32) (push) Has been cancelledCI / integration-user (33) (push) Has been cancelledCI / integration-user (34) (push) Has been cancelledCI / integration-user (35) (push) Has been cancelledCI / integration-full-restore (push) Has been cancelledreleased this
2026-10-08 01:28:55 +02:00 | 208 commits to main since this releaseBugfix release.
Added
- README: notes on using a Hetzner Storage Box over WebDAV and SMB.
Fixed
- Adding a backup location in the web interface failed with "Request failed with status code 403"
when the login was more than 30 minutes old: the form did not ask for password confirmation. - Settings page: the "Backup and restore" / "Settings" tabs line up with the sections below them.
- Backups: the runs table scrolls horizontally on narrow screens instead of running off the page.
occ backup:verify --deep: a blob that could not be read (network or storage error) was reported
as "corrupted or tampered". Reads are now retried, and a read that keeps failing is reported
separately as unreadable, with the error (run the check again; if the same blobs stay unreadable,
their pack may be damaged or truncated). Only a blob that was read but fails decryption or its
hash check counts as corrupted. Found on a Hetzner Storage Box over WebDAV, where the blob
turned out to be intact.
Package
ng_backup-0.9.2.tar.gzis the signed app store package (code-signed with the Nextcloud certificate forng_backup);.sigis its app store signature.Downloads
-
v0.9.1-beta.2 — first app store release
Pre-ReleaseCI / unit (8.2) (push) Has been cancelledCI / unit (8.3) (push) Has been cancelledCI / unit (8.4) (push) Has been cancelledCI / psalm (push) Has been cancelledCI / integration (mariadb, 32) (push) Has been cancelledCI / integration (mariadb, 33) (push) Has been cancelledCI / integration (mariadb, 34) (push) Has been cancelledCI / integration (mariadb, 35) (push) Has been cancelledCI / integration (pgsql, 32) (push) Has been cancelledCI / integration (pgsql, 33) (push) Has been cancelledCI / integration (pgsql, 34) (push) Has been cancelledCI / integration (pgsql, 35) (push) Has been cancelledCI / integration (sqlite, 32) (push) Has been cancelledCI / integration (sqlite, 33) (push) Has been cancelledCI / integration (sqlite, 34) (push) Has been cancelledCI / integration (sqlite, 35) (push) Has been cancelledCI / integration-targets (push) Has been cancelledCI / integration-user (32) (push) Has been cancelledCI / integration-user (33) (push) Has been cancelledCI / integration-user (34) (push) Has been cancelledCI / integration-user (35) (push) Has been cancelledCI / integration-full-restore (push) Has been cancelledreleased this
2026-10-07 18:09:36 +02:00 | 217 commits to main since this releaseSecond beta, the first release in the Nextcloud app store (signed).
Added
- App store listing: screenshots, website, repository and documentation link in
appinfo/info.xml.
Fixed
- Restore: the "new folder" option showed
"Restored "without the date pattern. - Restore: the restore-point dropdown cut off the time.
- Settings: the passphrase actions are on one line instead of stacked.
docs/HOWTO.md: the SFTP example used a non-existent auth mechanism (sftp::password
instead ofpassword::password).
Package
ng_backup-0.9.1.tar.gzis the signed app store package (code-signed with the Nextcloud certificate forng_backup);.sigis its app store signature.Downloads
- App store listing: screenshots, website, repository and documentation link in
-
v0.9.0-beta.1 — first beta
Pre-ReleaseCI / unit (8.2) (push) Has been cancelledCI / unit (8.3) (push) Has been cancelledCI / unit (8.4) (push) Has been cancelledCI / psalm (push) Has been cancelledCI / integration (mariadb, 32) (push) Has been cancelledCI / integration (mariadb, 33) (push) Has been cancelledCI / integration (mariadb, 34) (push) Has been cancelledCI / integration (mariadb, 35) (push) Has been cancelledCI / integration (pgsql, 32) (push) Has been cancelledCI / integration (pgsql, 33) (push) Has been cancelledCI / integration (pgsql, 34) (push) Has been cancelledCI / integration (pgsql, 35) (push) Has been cancelledCI / integration (sqlite, 32) (push) Has been cancelledCI / integration (sqlite, 33) (push) Has been cancelledCI / integration (sqlite, 34) (push) Has been cancelledCI / integration (sqlite, 35) (push) Has been cancelledCI / integration-targets (push) Has been cancelledCI / integration-user (32) (push) Has been cancelledCI / integration-user (33) (push) Has been cancelledCI / integration-user (34) (push) Has been cancelledCI / integration-user (35) (push) Has been cancelledCI / integration-full-restore (push) Has been cancelledreleased this
2026-10-07 01:15:40 +02:00 | 223 commits to main since this releaseFirst beta. Tested thoroughly and usable alongside your current backup, but not yet a
drop-in replacement for it. We test what we can ourselves (Nextcloud 32–35, SQLite, MariaDB and
PostgreSQL, S3, SFTP, FTP, SMB and NFS), but we need field experience from other setups: please
report what works and what doesn't, especially on large instances and on storage providers not
listed in the README.Added
- Disaster recovery:
occ backup:key:importandocc backup:restore:fullrestore the database,
data directory and config onto a fresh installation of the same major version. - Per-user backup and restore via user_migration:
occ backup:user:backupand
occ backup:user:restore(replace the account after a safety export, or restore as
<uid>-bak), also onto a server where the user does not exist yet. The commands ask before
installing user_migration (or take--install-user-migration). - Checksum audit:
occ backup:verify, shallow or--deep, for snapshots and per-user exports. - Retention for per-user exports:
occ backup:retention --user-last=N. - FTP and SMB covered by the integration tests; NFS through the
localbackend on a mounted share. docs/HOWTO.md: step by step from setup to a tested restore.- Warnings when a backup finishes with unreadable files or folders, or with files that kept
changing while being read (log,occ, notification, snapshot).
Changed
backup:restore:fullrefuses on an installation with more than one user and asks first;
backup:user:restore --mode=replaceasks before deleting an existing account (--forcefor
scripts in both cases).- A failed scheduled backup is retried at most three times a day, an hour apart.
- The recovery kit carries the deletion delay; the kit file is created owner-only.
- Adding a location through the web API needs password confirmation.
Fixed
- Exports of users whose id contains
.part-could be deleted by cleanup on remote locations. - Cleanup no longer frees the data of a per-user export whose manifest is missing.
- Crash safety of moving snapshots to and from the trash, of catalog writes by concurrent
backups and per-user exports, and of short uploads. - A file that keeps changing no longer makes a backup restart forever.
- Long restores and exports keep their lock on the location alive.
- Floating-point database columns are dumped exactly.
Known limitations
See "Known limitations" in the README: memory use on very large instances, never two servers
writing to one location, removing a passphrase slot does not revoke access, no rollback detection
before a disaster recovery, and a few smaller points. None of them block the road to 1.0.0; they
are on the backlog inPLAN.md.Downloads
- Disaster recovery: