Skip to main content
Version: v5

Backup Operations

Operations for backing up and restoring databases. For how the backup system works, its limitations, and worked examples, see the Backups Overview.

All backup operations require a super_user role when invoked through a running server; run offline (from the CLI with the server stopped), they are governed by filesystem permissions instead. All accept a database parameter that defaults to data. The engine badge on each operation indicates which storage engines support it: the managed-backup operations require RocksDB, while get_backup works with both RocksDB and LMDB.

OperationDescriptionRole Required
create_backupCreates a managed, incremental directory backup of a database (job)super_user
list_backupsLists the managed backups for a databasesuper_user
verify_backupVerifies a managed backup's integrity (job)super_user
delete_backupDeletes a single managed backupsuper_user
purge_backupsDeletes all but the newest keep_count managed backupssuper_user
restore_backupRestores a database from a managed backup (job)super_user
get_backupStreams a full snapshot of a database in the response for downloadsuper_user

Running backup operations from the CLI

Every operation on this page can be run from the CLI under its operation name, for example harper create_backup database=data. When Harper is running, the CLI forwards the operation to the server; when it is stopped, the command operates directly on the database and backup files. get_backup is the exception — it streams from a running server and has no offline form.

Like any CLI operation, backup commands also accept a remote target=<url> to run against another instance instead of the local one (see Remote Operations). With a remote target the operation is always forwarded — there is no offline path.

Offline invocation matters most for restore: an in-place restore_backup of the system database, or of any database a loaded component keeps open, must be run with the server stopped. See "when can a database be restored".

create_backup

Added in: v5.2.0 Engine: RocksDB

Creates an incremental directory backup of the database under the configured backup root (storage.backupPath, default <rootPath>/backup). Through a running server this runs as a background job: the operation returns a job_id immediately, and get_job reports the outcome including the new backup_id, size, and timestamp.

Backups of the same database share unchanged RocksDB data files, so the second and subsequent backups only copy the data that changed. The transaction-log snapshot — and the blob snapshot, if the database has file-backed blobs — is copied in full on every backup, so those portions are not incremental; with a large audit-retention window, frequent backups are not free for them. Pass exclude_blobs: true to skip the blob snapshot. Use purge_backups to manage retention.

{ "operation": "create_backup", "database": "data" }
harper create_backup database=data

list_backups

Added in: v5.2.0 Engine: RocksDB

Returns the managed backups for a database, each with:

  • backup_id — the monotonic integer identifier.
  • timestamp — creation time in seconds since the epoch.
  • size — bytes of the backup's RocksDB file payloads.
  • file_count — number of RocksDB files (some are shared across backups).

size and file_count come from the RocksDB backup engine and exclude the transaction-log and blob snapshots, so they undercount the repository's true on-disk footprint. Returns an empty array if no backups have been created yet.

{ "operation": "list_backups", "database": "data" }
harper list_backups database=data

verify_backup

Added in: v5.2.0 Engine: RocksDB

Verifies a managed backup's RocksDB file sizes — and their checksums when verify_checksum is true (slower) — together with the framing of its transaction-log snapshot (always checked). The blob snapshot is not verified. Through a running server this runs as a background job. backup_id is required.

{ "operation": "verify_backup", "database": "data", "backup_id": 1, "verify_checksum": true }
harper verify_backup database=data backup_id=1 verify_checksum=true

delete_backup

Added in: v5.2.0 Engine: RocksDB

Deletes a single managed backup. Files shared with other backups are reference-counted and removed only when no remaining backup references them. backup_id is required.

{ "operation": "delete_backup", "database": "data", "backup_id": 1 }
harper delete_backup database=data backup_id=1

purge_backups

Added in: v5.2.0 Engine: RocksDB

Deletes all but the newest keep_count managed backups, returning the number deleted and the number remaining.

{ "operation": "purge_backups", "database": "data", "keep_count": 3 }
harper purge_backups database=data keep_count=3

restore_backup

Added in: v5.2.0 Engine: RocksDB

Restores a database in place from a managed backup. backup_id defaults to the latest backup. The audit/transaction log is restored alongside the data, and — for a database with file-backed blobs — the blob roots are purged and rewritten from the backup's blob snapshot.

Through a running server this runs as a background job: Harper closes the database across all worker threads, restores it, and reloads it. This works only when no loaded component is holding the database open — if one does, the job ends in ERROR (surfaced by get_job) telling you to restore offline. Restoring the system database is rejected up front, before a job is created, as is target_database while the server is running. These cases require running the command from the CLI with the server stopped. See when can a database be restored?

From the CLI with the server stopped, target_database=<name> restores into a separate database instead of overwriting the source. The target must not already exist, or must be an empty directory; Harper picks the new database up on the next start.

If a restore is interrupted before it completes (crash, power loss), Harper marks the database as incompletely restored and refuses to load it on the next start, logging an incomplete-restore error. Recover by rerunning restore_backup for the same database and backup_id — do not try to load or hand-repair the directory.

{ "operation": "restore_backup", "database": "data", "backup_id": 1 }
harper restore_backup database=data backup_id=1
# restore into a new database instead of overwriting the source (server stopped)
harper restore_backup database=data backup_id=1 target_database=data_restored

get_backup

Engines: RocksDB, LMDB

Streams a full snapshot of the specified database in the HTTP response for download — there is no server-side artifact and nothing to clean up. The server must be running; this is the one backup operation with no offline form. Behavior depends on the storage engine:

  • RocksDB Changed in: v5.2.0 — streams a tar archive of the current database state — all tables, the transaction log, and any file-backed blobs — gzipped by default (gzip is a RocksDB-only option and compresses the snapshot substantially). Pass "gzip": false for a plain tar, or "exclude_blobs": true to leave blobs out. The snapshot is always the current state; downloading a specific historical backup_id is not supported — to move a retained managed backup off-host, copy its whole per-database backup repository (see Limitations). Restoring a RocksDB snapshot by hand takes an extra step when the database has blobs — see download a snapshot and restore it manually.
  • LMDB — streams the .mdb file. Specify "table" for a single table or "tables" for a set, and "include_audit": true to include the audit store. These options are LMDB-only.
{ "operation": "get_backup", "database": "data" }

From the CLI, pass out=<path> to choose the output file (defaults to a name derived from the response):

harper get_backup database=data out=./data.tar.gz
harper get_backup database=data target=https://node-2.example.com:9925 out=./data.tar.gz