Backup & restore
Full walkthrough — from first setup to recovering on a new machine.
Before you begin: build your recovery kit
Do this once, right after setting up backups. Your recovery kit is two items that you store together in 1Password (or a secure drive):
- Encryption key — a base64 string that decrypts all your backups and attachments.
- Settings export — a JSON file with your R2 credentials, bucket names, and configuration.
First-time setup
Step 1 — Create a backup bucket
Create a dedicated R2 bucket for backups (e.g. qalatra-backups). Keep it separate from your attachment bucket. Use the same Cloudflare account and the same access credentials.
Step 2 — Generate your encryption key
- Open Qalatra → Settings → Encryption & Backup tab.
- Click Generate key. The key is saved to macOS Keychain — you won't see it again unless you export it.
- Click Export key. A base64 string appears in a copyable textarea.
- Copy it and save it in 1Password as a secure note titled "Qalatra encryption key".
Step 3 — Configure the backup bucket
- In Settings → Encryption & Backup, enter your Backup Bucket Name (e.g.
qalatra-backups). - Click Save (at the bottom of the tab).
- Click Run backup now to confirm everything works. You should see "Backup complete (N KB)".
Step 4 — Export your settings
- Still in Settings → Encryption & Backup, scroll to Recovery Kit.
- Click Export settings. A JSON block appears.
- Copy it and save it in 1Password as a secure note titled "Qalatra settings".
Your recovery kit is now complete. Backups run automatically every hour and on app quit.
Restoring a backup on the same machine
- Open Settings → Encryption & Backup.
- Click Show backup history to load the list from R2.
- Find the backup you want (most recent is at the top) and click Restore.
- Confirm the prompt. Qalatra stages the file as
tasks.db.restore. - Quit and relaunch Qalatra. The restore is applied on startup. Your previous database is saved as
tasks.db.pre-restorein case you need to roll back.
Recovering on a new machine
Your laptop died, you got a new Mac, or you're setting up a second machine. Here's the full recovery flow.
Step 1 — Install Qalatra
Download and install Qalatra from the GitHub releases page. Launch it once to initialize the database.
Step 2 — Import your settings
- Open Settings → Encryption & Backup → Recovery Kit section.
- Paste your settings JSON (from 1Password) into the Import Settings textarea.
- Click Import. Your R2 endpoint, credentials, bucket names, and other config are restored.
- Quit and relaunch the app so the new settings are fully applied.
Step 3 — Import your encryption key
- Open Settings → Encryption & Backup → Encryption Key section.
- Paste your base64 key (from 1Password) into the Import key field.
- Click Import. The key is stored in the new machine's Keychain.
Step 4 — Restore your backup
- Click Show backup history. Your backups appear — the most recent is at the top.
- Click Restore on the backup you want.
- Confirm, then quit and relaunch. Your tasks, projects, habits, and notes are restored.
Backup retention
Backups older than 30 days are pruned automatically after every backup run. The pruning happens in the background — no manual cleanup needed. If you want to keep a backup indefinitely, download the .db.enc file from R2 and store it separately.
Manual backup file format
If you ever need to decrypt a backup manually (e.g. with a custom script):
# Each .db.enc file has this layout:
# bytes 0–11 : 12-byte AES-GCM IV (random, unique per file)
# bytes 12–27 : 16-byte GCM auth tag
# bytes 28+ : ciphertext (AES-256-GCM encrypted SQLite)
# Decrypt with Node.js:
import { createDecipheriv } from 'crypto'
import { readFileSync, writeFileSync } from 'fs'
const key = Buffer.from('<your base64 key>', 'base64')
const data = readFileSync('tasks-2026-05-10T12-00-00.db.enc')
const iv = data.subarray(0, 12)
const authTag = data.subarray(12, 28)
const enc = data.subarray(28)
const dec = createDecipheriv('aes-256-gcm', key, iv)
dec.setAuthTag(authTag)
writeFileSync('tasks.db', Buffer.concat([dec.update(enc), dec.final()]))FAQ
What happens if a backup fails?
The failure is logged and lastBackupStatus is set to failed. The next scheduled run retries automatically. You can also click Run backup now in Settings to force a retry and see the error message.
Can I back up to a different S3-compatible provider?
Yes. The backup bucket uses the same endpoint, access key, and secret as your attachment bucket — just a different bucket name. Any S3-compatible provider (Backblaze B2, AWS S3, MinIO, etc.) works.
Is the local database encrypted?
No. The local SQLite file is plaintext. Use FileVault (macOS) or BitLocker (Windows) for full-disk encryption if that matters to you. The encryption Qalatra provides is specifically for data in transit to and at rest in cloud storage (R2).