# ADR 0006 — Decoupled backup streams (files vs DB vs logs) **Status:** Accepted ## Context An earlier proposal wrote per-database dumps *into* each customer's ZFS dataset just before snapshotting, so one snapshot contained files + DB. Problem: the dump changes every night even for a static site, so every incremental `zfs send` would ship a fresh dump — defeating the cheap-incremental goal of [ADR 0005](0005-zfs-per-customer.md). Logs in the dataset cause the same bloat. ## Decision Back up each data type with the mechanism that fits its change pattern, in **three decoupled streams**: 1. **Web files** → ZFS snapshot + `zfs send` offsite (truly incremental; near-zero when unchanged). 2. **Databases** → **automysqlbackup** produces per-database dumps with daily/weekly/monthly rotation into `tank/platform/db-backups/`, then **rsync** offsite. Per-database dumps preserve per-customer restore granularity. 3. **Logs** → shipped to **Loki** via Promtail; never stored in the customer dataset. ## Consequences - ✅ Unchanged sites cost almost nothing to back up offsite. - ✅ Each stream is independently tunable (retention, cadence, target). - ❌ Restoring a customer is a **two-step** operation (files from ZFS, DB from the dump repo) rather than a single snapshot rollback — documented in the [DR runbook](../06-backup-and-dr.md). - ⚠️ The streams are **crash-consistent, not atomically consistent**. Schedule the nightly DB dump close to the ZFS snapshot; the small window is harmless for PHP/WordPress (files-on-disk + DB-rows). - ↔️ Optional future: place `db-backups` on its own dataset and `zfs send` it for checksummed/immutable offsite instead of rsync.