--- title: Immich on ZFS description: Moving Immich to its own ZFS dataset published: true date: 2026-02-06T15:57:04.261Z tags: service zfs immich dataset editor: markdown dateCreated: 2026-02-06T15:57:04.261Z --- # Moving Immich to a ZFS Dataset ## Overview This guide covers moving an existing Immich installation to its own ZFS dataset to enable `zfs send` backups. ## Prerequisites - ZFS pool mounted at `/srv/vault` - Existing Immich installation at `/srv/vault/immich` - Immich running via Docker Compose ## Steps ### 1. Stop Immich Services ```bash cd /srv/vault/immich # or wherever your docker-compose.yml is docker compose down ``` ### 2. Create the New Dataset ```bash sudo zfs create vault/immich ``` ### 3. Move Existing Data Temporarily ```bash sudo mv /srv/vault/immich /srv/vault/immich_old ``` ### 4. Set Mountpoint and Mount Dataset ```bash sudo zfs set mountpoint=/srv/immich vault/immich sudo zfs mount vault/immich ``` ### 5. Copy Data to New Dataset ```bash sudo rsync -avxHAX /srv//immich_old/ /srv/immich/ ``` Flags preserve permissions, ownership, and special attributes. ### 6. Verify Data Copy ```bash sudo du -sh /srv/vault/immich_old sudo du -sh /srv/vault/immich ``` Sizes should match closely. ### 7. Start Immich ```bash cd /srv/vault/immich docker compose up -d ``` ### 8. Test and Clean Up Verify everything works, then remove old data: ```bash sudo rm -rf /srv/vault/immich_old ``` ## ZFS Dataset Properties ### Recommended Settings ```bash # Compression - helps with photos and database sudo zfs set compression=lz4 vault/immich # Record size - balance for mixed workload sudo zfs set recordsize=128K vault/immich # Better database performance sudo zfs set primarycache=all vault/immich sudo zfs set atime=off vault/immich ``` ### Property Explanations - **compression=lz4**: Fast, low CPU overhead, works well for both photos and database - **recordsize=128K**: Good compromise between database (8K blocks) and photos (larger files) - **atime=off**: Disables access time updates, reduces unnecessary writes - **primarycache=all**: Keeps both metadata and data in ARC cache (default) ## Backup with ZFS Send/Receive ### Create Snapshot ```bash zfs snapshot vault/immich@backup-$(date +%Y%m%d) ``` ### Send to Remote Server ```bash zfs send vault/immich@backup-$(date +%Y%m%d) | ssh backup-server zfs receive tank/backups/immich ``` ### Incremental Backups ```bash # After first full backup zfs snapshot vault/immich@backup-$(date +%Y%m%d) zfs send -i vault/immich@previous-snapshot vault/immich@backup-$(date +%Y%m%d) | \ ssh backup-server zfs receive tank/backups/immich ``` ## Optional: Separate Datasets for Database and Photos For optimal performance, split into separate datasets: ```bash sudo zfs create vault/immich/database sudo zfs create vault/immich/photos # Database optimized sudo zfs set recordsize=16K vault/immich/database sudo zfs set logbias=latency vault/immich/database # Photos optimized sudo zfs set recordsize=1M vault/immich/photos ``` Then update your Docker Compose volume mounts accordingly.