Older Backup Formats
Every backup job now writes a seekable archive. Before that, jobs that backed up only databases wrote other formats, and DBackup still restores and downloads them. This page lists the code that exists only for those formats, so it can be removed deliberately once it is no longer needed.
The formats
| Format | What it looks like | How it is recognised |
|---|---|---|
| Single dump file | backup.sql, .sql.gz, .sql.br, optionally .enc, compressed and encrypted as a whole | .meta.json without an archive block, or the file extension |
| Multi-database TAR | backup.tar, optionally .gz / .br / .enc as a whole, with manifest.json version 1 plus one dump per database | isMultiDbTar() inside each adapter's restore() |
MSSQL TAR of .bak files | A TAR of .bak files without any manifest, still named .bak | checkIfTarArchive() in mssql/restore.ts |
Finding the code
Every place is marked with a comment that starts with LEGACY-FORMAT:
grep -rn "LEGACY-FORMAT" src scriptsThe tag in parentheses says what the code is and when it can go:
| Tag | Meaning | Remove when |
|---|---|---|
LEGACY-FORMAT(write) | Code that produced the older formats. Nothing calls it anymore except tests. | Now. See Stage 1. |
LEGACY-FORMAT(read) | Code that reads backups in the older formats. | Only once those backups no longer need restoring. See Stage 2. |
LEGACY-FORMAT(shared) | Looks like it belongs to the older formats, but config backups still use whole-file compression and encryption. | Never together with the rest. See What stays. |
Do not search for the word "legacy" alone. It also names unrelated things, such as the PostgreSQL compression setting, per-destination retention JSON and the MSSQL file transfer mode.
Stage 1: the writer
This can be done at any time, it changes nothing for existing backups.
- [ ] Remove
dump()fromDatabaseAdapterinsrc/lib/core/interfaces.tsand from the adapter registrations in eachindex.ts. - [ ] Delete
dump()inmysql,postgres,mongodb,firebird,mssqlandazure-sql, including the multi-database branches and the MSSQL TAR packer. Keep any per-database helperdumpOne()still calls. - [ ] Move the body of
dump()intodumpOne()forsqliteandredis, which currently wrap it. - [ ] Remove the whole-file compression and encryption in
src/lib/runner/steps/03-upload.ts, together with thecompression,encryptionandmultiDbfields it writes into the metadata sidecar. TheisSeekableArchiveguard then has nothing left to guard. - [ ]
createMultiDbTar()andTarFileEntrystay until stage 2, because the tests for the reader build their fixtures with them. Move them into a test helper if stage 2 is far off. - [ ] Rewrite or delete the tests that call
dump():tests/unit/adapters/database/{mysql,postgres,mongodb,azure-sql,redis,sqlite}/dump.test.ts,tests/unit/adapters/mssql/dump.test.ts,tests/unit/adapters/database/firebird.test.ts, the.gzand.enccases intests/unit/runner/steps/03-upload.test.ts, andtests/integration/{backup,multidb-backup,ssh-mode}.test.ts. - [ ] Update
docs/developer-guide/adapters/database.mdandsrc/lib/adapters/CLAUDE.md, which still describedump()as part of the interface.
Stage 2: the reader
DBackup cannot tell whether anyone still holds a backup in an older format. Retention eventually deletes them from a destination, but locked backups, long retention policies and copies taken elsewhere can keep them around for years. Removing the reader turns those backups into files only the Recovery Kit can open, so it needs a release with a breaking change note that tells users to restore or re-create what they still need first.
- [ ] Restore pipeline: in
src/services/restore/pipeline.ts, reject a backup without anarchiveblock instead of downloading, decrypting and decompressing it. The metadata fields and the extension fallback marked there go too. - [ ] Adapters: remove
restore()fromDatabaseAdapter. Delete it inmysql,postgres,mongodb,firebird,mssqlandazure-sql, and move its body intorestoreOne()forsqliteandredis, which currently wrap it. - [ ] Analysis: remove
analyzeDumpfrom the interface and everyanalyze.ts(plusanalyzeDumpinazure-sql/restore.ts), and the metadata shortcuts and download fallback insrc/app/api/storage/[id]/analyze/route.ts. Keep that route's fallback to the embedded index of a seekable archive whose sidecar is missing. - [ ] TAR utilities: move
createTempDir,cleanupTempDir,shouldRestoreDatabaseandgetTargetDatabaseNameout ofcommon/tar-utils.ts, then deletecommon/tar-utils.tsandcommon/types.ts. - [ ] Metadata: remove
multiDbfromBackupMetadata. - [ ] UI: remove
classicModefromrestore-validation.tsand what depends on it inrestore-client.tsx, and thefile.namebranch inredis-restore-wizard.tsx. - [ ] Recovery Kit: remove
unpackMultiDbTar()fromscripts/dbackup-recover.js.--decryptstays for config backups. - [ ] Tests:
tests/unit/services/restore-legacy-formats.test.ts,tests/unit/services/restore-pipeline*.test.ts, the multi-database cases in the adapterrestore.test.tsfiles,tests/unit/adapters/database/{mysql,postgres,mongodb}/analyze.test.ts,tests/unit/adapters/database/common/tar-utils.test.ts, the older-format cases intests/unit/lib/storage-analyze-route.test.tsandtests/unit/lib/recovery-kit-archive.test.ts, andtests/integration/{restore,multidb-restore}.test.ts. - [ ] Docs: the older-format passages in
docs/user-guide/security/recovery-kit.md,encryption.mdandcompression.md,docs/user-guide/features/{restore,storage-explorer,api-reference}.md,docs/user-guide/sources/{mssql,azure-sql,redis}.md, the multi-database TAR section indocs/developer-guide/adapters/database.md, the info box at the top of the archive format reference, and this page.
What stays
Config backups are written as a .tar.gz, encrypted as a whole with the same AES-256-GCM stream the older database backups used. Everything marked LEGACY-FORMAT(shared) serves them and has to survive both stages:
src/lib/crypto/stream.tsand the compression streamsresolveDecryptionKey()andlegacyHeadVerifier()insrc/services/restore/smart-recovery.ts, and the whole-file branch insrc/services/backup/key-recovery.ts- The whole-file decryption and the
.enczip branch instorageService.downloadFile() compressionandencryptioninBackupMetadata- The branch for rows without a file index in
src/components/dashboard/storage/download-options.ts restoreWholeFile()and--decryptin the Recovery Kit