Storage & backup
Where your data lives, how it's protected, and how to move it.
Local database
Qalatra stores everything in a single SQLite file at ~/IdeaProjects/qalatra/db/tasks.db (configurable). The schema migrates automatically on launch — idempotent ALTER TABLE statements, safe to run repeatedly. Downgrading across a schema version is not supported; restore from a backup instead.
Cloud backup (R2)
Qalatra can back up your database to a Cloudflare R2 bucket automatically. Backups are encrypted client-side before upload — nothing unencrypted ever leaves your machine.
What you need
- An R2 bucket dedicated to backups (e.g.
qalatra-backups) — separate from your attachment bucket. - An encryption key generated in Settings → Encryption & Backup.
- The same R2 credentials (endpoint, access key, secret) you configured for attachments.
Setting it up
Open Settings → Encryption & Backup. Click Generate key — the key is stored in macOS Keychain via safeStorage and never written to disk in plaintext. Then set the Backup Bucket Name and click Save.
How backups work
- Automatic — hourly. A timer fires every 60 minutes while the app is open.
- Automatic — on quit. The app runs a best-effort backup with a 10-second timeout before exiting.
- Manual. Settings → Encryption & Backup → Run backup now.
Each backup is a full copy of the database, encrypted with AES-256-GCM. The wire format is 12-byte IV + 16-byte auth tag + ciphertext, stored as db/tasks-YYYY-MM-DDTHH-MM-SS.db.enc in your R2 bucket. Backups older than 30 days are pruned automatically after each run.
Restoring a backup
Settings → Encryption & Backup → Show backup history. Each entry shows the date and file size. Click Restore on the one you want — Qalatra downloads, decrypts, and stages the file as tasks.db.restore. Restart the app to apply it. The current database is preserved as tasks.db.pre-restore before the swap.
For full recovery steps on a new machine, see Backup & restore walkthrough.
Attachments
Files are always cached locally in the attachment cache directory (configurable in Settings → Storage). When R2 is configured with an encryption key, files are encrypted before upload. Opening an encrypted attachment downloads and decrypts it locally — nothing unencrypted touches the cloud.
Attachments not yet uploaded (e.g. added while offline) are queued as pending. Settings → Storage → Sync Pending uploads them all at once.
Encryption
Qalatra uses AES-256-GCM with a unique 12-byte random IV per file. The encryption key is a 32-byte random value stored in macOS Keychain via Electron safeStorage — the same mechanism used by password managers. The key never touches the filesystem in plaintext.
Recovery kit
Your recovery kit has two pieces. Store both in 1Password (or equivalent):
- Encryption key — base64 string from Settings → Encryption & Backup → Export key.
- Settings export — JSON from Settings → Encryption & Backup → Export settings (contains your R2 credentials, bucket names, etc.).
With these two items you can recover everything on any machine.
Schema evolution
Qalatra migrates the SQLite schema on launch. Migrations use ALTER TABLE … ADD COLUMN wrapped in try/catch so they're idempotent. Downgrading across a schema version is not supported — if you roll back, restore from backup first.