Backup & Restore
nodyn stores all persistent data in ~/.nodyn/. This includes run history, knowledge graph, memory, secrets vault, and configuration. The backup module provides crash-safe snapshots with optional encryption.
What Gets Backed Up
Section titled “What Gets Backed Up”| Data | Storage | Backup Method |
|---|---|---|
Run history (history.db) | SQLite WAL | VACUUM INTO (crash-safe) |
Secrets vault (vault.db) | SQLite WAL | VACUUM INTO (crash-safe) |
Data store (datastore.db) | SQLite WAL | VACUUM INTO (crash-safe) |
Knowledge graph (knowledge-graph/) | LadybugDB (Kuzu) | Directory copy |
Memory (memory/) | Text files | Recursive copy |
Config (config.json) | JSON | File copy |
Sessions (sessions/) | JSON files | Recursive copy |
VACUUM INTO creates an atomic, consistent snapshot of each SQLite database — even while nodyn is running with active writes. No data corruption risk.
CLI Commands
Section titled “CLI Commands”/backup # Create a backup now/backup list # List all backups with dates and sizes/backup verify # Verify integrity of the latest backup/backup verify NAME # Verify a specific backup/backup prune # Remove old backups (retention policy)/backup restore # Restore from the latest backup (with confirmation)/backup restore NAME # Restore from a specific backupConfiguration
Section titled “Configuration”{ "backup_dir": "~/.nodyn/backups", "backup_schedule": "0 3 * * *", "backup_retention_days": 30, "backup_encrypt": true}| Field | Default | Description |
|---|---|---|
backup_dir | ~/.nodyn/backups | Where backups are stored |
backup_schedule | 0 3 * * * | Cron schedule for automatic backups (daily 3 AM) |
backup_retention_days | 30 | Days to keep old backups. 0 = never auto-delete |
backup_encrypt | true (if vault key set) | Encrypt backups with AES-256-GCM |
All fields are PROJECT_SAFE_KEYS — can be set in project-level .nodyn/config.json.
Encryption
Section titled “Encryption”When NODYN_VAULT_KEY is set and backup_encrypt is not explicitly false, backups are encrypted:
- Algorithm: AES-256-GCM (same as vault and run history)
- Key derivation: HKDF-SHA256 from vault key with backup-specific salt
- Per-file encryption: Each file encrypted individually with unique IV
- File format:
NBAKmagic header + version + IV + auth tag + ciphertext - Manifest stays readable: Only file contents are encrypted, not the manifest
Without a vault key, backups are unencrypted. The CLI warns about this.
Backup Structure
Section titled “Backup Structure”~/.nodyn/backups/ 20260325T030000Z/ manifest.json # Metadata, file list, checksums history.db # VACUUM INTO copy (or encrypted) vault.db # VACUUM INTO copy (or encrypted) datastore.db # VACUUM INTO copy (or encrypted) knowledge-graph/ # Directory copy memory/ # Recursive copy config.json # File copyManifest
Section titled “Manifest”Every backup includes a manifest.json with:
{ "version": "1.0.0", "created_at": "2026-03-25T03:00:00.000Z", "nodyn_dir": "/home/user/.nodyn", "encrypted": true, "files": [ { "path": "history.db", "size_bytes": 524288, "checksum_sha256": "a1b2c3...", "type": "sqlite" } ], "checksum": "overall-sha256..."}Verification
Section titled “Verification”/backup verify checks:
- Every file in the manifest exists
- File sizes match
- SHA-256 checksums match
- SQLite databases pass
PRAGMA integrity_check(unencrypted backups only)
Restore Safety
Section titled “Restore Safety”Restore always creates a safety backup first before overwriting any data:
- Safety backup of current state →
~/.nodyn/backups/<timestamp>/ - If encrypted: decrypt each file
- Replace current files with backup contents
- Prompt user to restart nodyn
If restore fails mid-way, the safety backup allows recovery. The safety backup path is shown in the output.
Pre-Update Backup
Section titled “Pre-Update Backup”nodyn automatically creates a backup when it detects a version change on startup. This protects against update regressions — if a new version breaks something, the pre-update backup is already there.
[nodyn] Version changed (1.0.0 → 1.1.0) — creating pre-update backup...[nodyn] Pre-update backup created: /home/nodyn/.nodyn/backups/20260326T030000ZHow it works:
- On
Engine.init(), the current version is compared with~/.nodyn/.last_version - If the version changed → backup before anything else runs
- The version file is updated after the check
- First-ever run writes the version file without triggering a backup
- If Google Drive is configured, the pre-update backup is also uploaded
No configuration needed — this is always active when the backup manager is initialized.
Scheduled Backups
Section titled “Scheduled Backups”When backup_schedule is configured and the WorkerLoop is running (Telegram, MCP server modes), backups run automatically as background tasks:
- Task type:
backup(no LLM call — direct BackupManager operation) - Auto-prune: Old backups are pruned after each scheduled backup
- Failure notification: Failed backups are reported via NotificationRouter (high priority)
Retention Policy
Section titled “Retention Policy”- Backups older than
backup_retention_daysare auto-deleted - The most recent backup is never deleted regardless of age
0disables auto-deletion- Manual pruning:
/backup prune
SDK Usage
Section titled “SDK Usage”import { BackupManager } from '@nodyn-ai/core';import { getNodynDir } from '@nodyn-ai/core';
const manager = new BackupManager(getNodynDir(), { backupDir: '/path/to/backups', retentionDays: 30, encrypt: true,}, process.env['NODYN_VAULT_KEY'] ?? null);
// Createconst result = await manager.createBackup();console.log(result.success, result.path);
// Listconst backups = manager.listBackups();
// Verifyconst check = manager.verifyBackup(backups[0].path);
// Restore (creates safety backup first)const restore = await manager.restoreBackup(backupPath);
// Pruneconst pruned = manager.pruneBackups(30);Google Drive Backup
Section titled “Google Drive Backup”When Google auth is configured with drive.file scope, backups are automatically uploaded to Google Drive after each local backup.
- Configure Google OAuth: set
GOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRET - Run
/google authin the CLI and grant thedrive.filescope - Backups will auto-upload to a
nodyn-backupsfolder on your Google Drive
CLI Commands
Section titled “CLI Commands”/backup gdrive list # List remote backups on Google Drive/backup gdrive upload # Force upload latest local backup/backup gdrive restore # Download and restore from Google DriveHow It Works
Section titled “How It Works”- A
nodyn-backupsfolder is auto-created in your Google Drive root - Each backup gets a subfolder named by timestamp
- All files (encrypted or not) are uploaded as binary
- Upload failures are logged but never fail the local backup
- Manifests are used to list remote backups without downloading full data
Configuration
Section titled “Configuration”{ "backup_gdrive": true}Set backup_gdrive: false to disable Google Drive upload while keeping Google auth active for other features.
Off-Site Safety
Section titled “Off-Site Safety”This is the recommended setup for pilots and production:
- Local backup → fast restore, survives container restart
- Google Drive → survives server failure, off-site disaster recovery
- Separate backup volume (Docker) → survives data volume corruption
Docker
Section titled “Docker”Mount a backup volume for persistent storage:
docker run -d \ -e ANTHROPIC_API_KEY=sk-ant-... \ -e NODYN_VAULT_KEY=... \ -v ~/.nodyn:/home/nodyn/.nodyn \ -v /mnt/backups:/home/nodyn/.nodyn/backups \ nodynOr configure backup_dir to an external path in config.