Storage Architecture#

Philosophy#

Start simple. No NAS/RAID until you have 3+ drives. Syncthing-first sync, thunderbolt cold backups, snapraid for phase 2.

Phase 1: Syncthing-First (What You Have Now)#

Value/Complexity Analysis (1TB Constraint)#

Current Setup (Best Value for Your Constraints)#

ComponentComplexityCostValue
Syncthing (3 nodes)Low$0High - real-time sync across all servers
Thunderbolt NVMe cold backupLow~$200 (drive)High - full disk images, air-gapped
Postgres-backed servicesLow$0High - single DB stack (authentik only)

Why This Works for 1TB Lithium#

  • Lithium is inference-only: Models live in /models synced from helium (2TB)
  • No local storage pressure: 1TB sufficient for OS, configs, and active models
  • Helium is the grunt server: 2TB NVMe handles container services + model storage
  • Hydrogen is gateway: 2TB NVMe for configs, DNS, Traefik, Pi-hole

What NOT to Do#

  • Don’t add Nextcloud: Redundant file sync when Syncthing exists
  • Don’t run MySQL alongside Postgres: Single DB stack reduces complexity
  • Don’t attempt RAID with 1 drive: Wait until you have 3+ drives for MergerFS + SnapRAID
  • Don’t over-provision storage on lithium: Inference workloads don’t need 2TB

Storage Allocation Strategy#

Helium (2TB):
  - /docker: 500GB (container configs + data)
  - /models: 1TB (LLM models for GPU inference)
  - /code: 200GB (synced via Syncthing)
  - /backups: 300GB (local snapshots)

Lithium (1TB):
  - /models: 600GB (active inference models)
  - /code: 200GB (synced via Syncthing)
  - /configs: 100GB (synced via Syncthing)
  - OS + swap: 100GB

Hydrogen (2TB):
  - /configs: 500GB (dotfiles, service configs)
  - /code: 200GB (synced via Syncthing)
  - /traefik: 100GB (certificates, configs)
  - Free space: 1.2TB (cold backups, future expansion)

Upgrade Path (When You Have More Storage)#

  1. Phase 2: Add 2nd NVMe to lithium (1TB → 2TB)
  2. Phase 3: Add 3rd drive to helium (2TB → 2+2TB) → MergerFS pool
  3. Phase 4: Add dedicated parity drive → SnapRAID

Setup#

hydrogen (2TB NVMe) ←→ helium (2TB NVMe) ←→ lithium (1TB NVMe)

Install syncthing on all three boxes:

# Ubuntu/Debian
sudo apt install syncthing

# Enable auto-start
systemctl enable --now syncthing@$(whoami)

Configure sync folders:

  • /code — active development projects
  • /configs — dotfiles, service configs
  • /models — LLM models (large, sync selectively)

How it works:

  • Files sync peer-to-peer automatically
  • All three boxes have copies — no single point of failure
  • If helium dies, hydrogen and lithium still have data

Thunderbolt Cold Backups#

Weekly backup schedule:

# Mount thunderbolt NVMe
sudo mount /dev/nvmeXn1 /mnt/backup

# Full image backup (helium)
sudo dd if=/dev/nvme0n1 of=/mnt/backup/helium-$(date +%Y%m%d).img bs=4M status=progress

# Unmount
sudo umount /mnt/backup

Schedule with cron:

0 3 * * 0 /usr/local/bin/weekly-backup.sh

Phase 2: MergerFS + SnapRAID (When You Have 3+ Drives)#

MergerFS Pool#

# Install
sudo apt install mergerfs

# Create pool directory
sudo mkdir -p /pool/data

# Add to /etc/fstab
/mnt/drive* /pool/data mergerfs defaults,allow_other,category.create=mfs 0 0

SnapRAID Parity#

# Install
sudo apt install snapraid

# Configure /etc/snapraid.conf
content = /pool/data/.snapraid/content
parity = /mnt/parity/snapraid.parity
data = /pool/data/drive1
data = /pool/data/drive2
data = /pool/data/drive3

Run nightly:

sudo snapraid sync

Backup Strategy Summary#

LayerFrequencyScopeRetention
SyncthingReal-timeActive projectsCurrent state
SnapRAIDDaily/nightlyAll pooled dataLast sync
Cold backupWeeklyFull disk image4 weeks
Backblaze B2ContinuousCritical configs/codeUnlimited

What RAID Is NOT#

  • Not a backup — ransomware still encrypts everything
  • Not cloud storage — you still manage it
  • Not necessary for 1 drive — RAID needs 2+ drives

What NAS Is NOT#

  • Not faster than local — network adds latency
  • Not magic — if the NAS dies, you’re stuck until rebuild