Backup
Scheduled snapshots & one-click restore
The backup block gives your service first-class data snapshots without bolting on external tooling. When enabled it mounts admin endpoints to create, list, download and (optionally) restore JSON snapshots of your tables, and can run them automatically on a cron schedule.
Each snapshot is a portable JSON document, retained up to a configurable count, with noisy operational tables excluded by default. Restore is gated behind both authentication and an explicit allowRestore flag so it can never fire by accident.
Storage & format#
Where snapshots live, how many are kept, and what they contain. Defaults are production-sane — additive retention with operational tables excluded.
1{2 "backup": {3 "enabled": true,4 "basePath": "/admin/backup",5 "storagePath": "./backups",6 "format": "json",7 "maxBackups": 50,8 "allowRestore": false,9 "excludeTables": ["audit_logs", "backup_logs"],10 "schedule": { "enabled": true, "cron": "0 2 * * *", "retentionDays": 30 }11 }12}enabledbooleanOptionalMount the backup service and its admin routes.
falsebasePathstringOptionalRoute prefix for the backup management endpoints.
"/admin/backup"storagePathstringOptionalFilesystem directory where snapshot files are written. Mount a persistent volume here in production.
"./backups"format'json'OptionalSnapshot serialization format. JSON keeps backups portable and human-inspectable.
"json"maxBackupsnumberOptionalHow many snapshots to keep. Older ones are pruned once the limit is exceeded.
50allowRestorebooleanOptionalWhether the restore endpoint is permitted to run. When false, restore attempts are rejected with 403 even for authenticated admins — a deliberate guard for production.
trueexcludeTablesstring[]OptionalTables omitted from snapshots — high-churn operational logs that would bloat backups and aren't business data.
["audit_logs","backup_logs"]Scheduled snapshots#
Opt into unattended backups on a cron cadence, with automatic pruning by age. Off by default — you decide when automation makes sense.
scheduleobjectOptionalCron-driven automatic backups.
enabledbooleanOptionalStart the cron scheduler on boot.
falsecronstringOptionalA cron-style expression, but parsed by a deliberately simple interval converter: it recognises */N in the hour field (every N hours) or the minute field (every N minutes), and otherwise falls back to a daily cadence. The default 0 2 * * * therefore means 'daily'. It is not a full cron engine — pick an interval, not a precise calendar time.
"0 2 * * *"retentionDaysnumberOptionalDelete scheduled snapshots older than this many days.
30Under the hood — BackupService#
Each backup is a single JSON file plus a row in backup_logs that tracks its lifecycle. Knowing the shape and the safeguards explains the retention and restore behaviour.
snapshot file{ manifest, data }OptionalcreateBackup writes {schema}_{timestamp}.json to storagePath: a manifest (version, schema, per-table row counts + columns, totalRows) and the data (every included table's rows). Tables are discovered from the live schema, minus excludeTables — so in multi-tenant mode you can snapshot a specific tenant schema.
backup_logsstatus lifecycleOptionalEvery run inserts a log row that moves running → completed | failed (and later → restored), recording size, table/row counts, trigger (manual | scheduled | pre_restore), who ran it and the cron used. listBackups reads the latest 100; downloads stream the file by id.
restore safeguardsrestoreFromBackupOptionalRestore refuses unless allowRestore is true and the source backup is completed. It first takes an automatic pre_restore snapshot, then per table DELETEs all rows and re-INSERTs the file's rows in chunks of 500 — so a botched restore is itself recoverable.
retentionmaxBackups + retentionDaysOptionalAfter every backup enforceMaxBackups prunes everything beyond the newest maxBackups; the scheduled run additionally calls cleanupExpiredBackups to drop anything older than retentionDays. Both delete the file and its log row together.
Related sections