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.

config.nucleus.json — backup
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}
enabledbooleanOptional

Mount the backup service and its admin routes.

Defaultfalse
basePathstringOptional

Route prefix for the backup management endpoints.

Default"/admin/backup"
storagePathstringOptional

Filesystem directory where snapshot files are written. Mount a persistent volume here in production.

Default"./backups"
format'json'Optional

Snapshot serialization format. JSON keeps backups portable and human-inspectable.

Default"json"
maxBackupsnumberOptional

How many snapshots to keep. Older ones are pruned once the limit is exceeded.

Default50
allowRestorebooleanOptional

Whether the restore endpoint is permitted to run. When false, restore attempts are rejected with 403 even for authenticated admins — a deliberate guard for production.

Defaulttrue
excludeTablesstring[]Optional

Tables omitted from snapshots — high-churn operational logs that would bloat backups and aren't business data.

Default["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.

scheduleobjectOptional

Cron-driven automatic backups.

enabledbooleanOptional

Start the cron scheduler on boot.

Defaultfalse
cronstringOptional

A 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.

Default"0 2 * * *"
retentionDaysnumberOptional

Delete scheduled snapshots older than this many days.

Default30

Under 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 }Optional

createBackup 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 lifecycleOptional

Every 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 safeguardsrestoreFromBackupOptional

Restore 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 + retentionDaysOptional

After 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