Hugin’s data lives in a single SQLite file (~/.hugin/hugin.db) plus the auxiliary directories under ~/.hugin/. The built-in Backup subsystem snapshots the SQLite database — atomically, via SQLite’s VACUUM INTO — into ~/.hugin/backups/ (or a custom directory).
🔗What Gets Backed Up
A database backup contains the live SQLite snapshot at the moment the backup ran:
- All flows, findings, projects, scope, intercept rules
- Repeater history, intruder configs, organiser entries
- Environments, scheduled jobs
- Any other data persisted in
hugin.db
What’s not in a database backup:
config.toml— config-as-code; back up your~/.hugin/config.tomlseparately- CA certificate + private key (
Hugin-Proxy-CA.pem+-key.pem) - Lua extensions (
~/.hugin/extensions/) - Synaps modules (
~/.hugin/modules/) - Dynamic MCP plugins (
~/.hugin/plugins/) - Hosted files (
~/.hugin/hosted/) - Wordlists (
~/.hugin/wordlists/)
For a full disaster-recovery snapshot, archive the entire ~/.hugin/ directory.
🔗Configuration
The [backup] section of ~/.hugin/config.toml:
[backup]
enabled = false # off by default; flip to true for auto-backup
interval_minutes = 30 # auto-backup interval when enabled
max_backups = 10 # retention — older backups auto-pruned
# backup_dir = "/custom/path" # default: ~/.hugin/backups/
When enabled = true, Hugin runs a background task that snapshots the database every interval_minutes. Older snapshots beyond max_backups are deleted to bound disk usage.
🔗Manual Backup (UI / API)
There’s no hugin backup CLI command. Backups are triggered through the desktop UI or the REST API.
🔗REST API
GET /api/backup List existing backups
POST /api/backup/create Create a backup now
POST /api/backup/restore Restore from a named backup
POST /api/backup/delete Delete a specific backup
backup_create calls HuginStore::backup_to() which uses SQLite’s VACUUM INTO — atomic, non-blocking, safe to run while the proxy is active.
🔗UI
Settings → Advanced exposes the backup operations: list, create, restore, delete.
🔗Restore
Restoring replaces the live hugin.db with the chosen backup. The proxy briefly pauses while the file is swapped, then resumes. Active proxy connections may need to reconnect.
Restore is invoked via POST /api/backup/restore with the backup’s filename. Done from the UI’s backup list with a Restore action.
🔗CA Backup
The CA cert and private key under ~/.hugin/ are not in the database backup. To preserve them across re-installs (so existing browsers continue trusting Hugin’s MITM):
cp ~/.hugin/Hugin-Proxy-CA.pem ~/secure-vault/
cp ~/.hugin/Hugin-Proxy-CA-key.pem ~/secure-vault/
To restore on a fresh install, copy them back into ~/.hugin/ before the first hugin start — Hugin uses the existing CA instead of generating a new one.
🔗Off-Site Backups
Hugin doesn’t ship cloud backup. Common patterns:
- rsync to a NAS — schedule a cron job that rsyncs
~/.hugin/backups/(or the whole~/.hugin/) to a NAS or remote host - Duplicity / restic / Borg — run any standard backup tool against
~/.hugin/ - Encrypted archive —
tar -czf - ~/.hugin | gpg -c > hugin-$(date +%F).tar.gz.gpg
For automated backup-then-ship workflows, combine the auto-backup feature with a Scheduler job that runs an rsync / upload command after each backup interval.
🔗Project Bundle vs Database Backup
Two different things:
| Database Backup | .huginproject Bundle | |
|---|---|---|
| Scope | All projects, all data | One project |
| Mechanism | VACUUM INTO SQLite snapshot | zstd-compressed JSON export |
| Use case | Disaster recovery / point-in-time | Hand-off / archive of one engagement |
| Restore replaces | The live database | Imports as a new project |
For periodic disaster-recovery snapshots: use database backup. For sharing one engagement with a teammate: use project bundle export.
🔗Database Size
Healthy database sizes:
- 100 MB — small project (~10k flows, no large bodies)
- 1 GB — medium project (~100k flows, mixed body sizes)
- 10 GB+ — large engagement (heavy crawling, long retention)
If the database grows faster than expected, check [storage].max_body_size in your config — large response bodies are the usual culprit. Default is 10 MB; lower it for projects where bodies don’t matter.