v0.9.0
CURRENT
2026-06-16
Multi-volume libraries + CAS thumbnail cache
Multi-volume libraries
- A library can now span multiple drives. New
library_volumes table tracks per-drive root, label, online status, capacity, free space, default flag.
photos.volume_id records which drive each photo lives on — "is this drive plugged in?" is now O(1).
- Migration 018 backfills a default volume per existing library so single-drive setups are unchanged.
- New commands:
volume_add / volume_list / volume_check / volume_remove / volume_set_default.
Thumbnail cache
- CAS-deeper layout:
<root>/<sha[0..2]>/<sha[2..4]>/<sha>-<size>.jpg. Old one-level layout bottomed out at ~4k files per dir on a 1M library; new layout caps any directory at ~256 entries.
- Existing v0.8.x caches are migrated lazily — when a thumbnail is requested we rename the legacy file into its new path rather than re-encoding from the original.
- Configurable
thumbs.root_override — move the entire cache to your external drive on TB-scale setups without uninstalling.
Importer
- Scanner records
volume_id on every new photo via longest-prefix match against library_volumes.
Minor version bump (0.8 → 0.9). DB migrates automatically. Existing libraries get a default volume so behaviour is unchanged unless you add more drives.
v0.8.2
2026-06-16
Sync resilience
Cloud sources
- 429 responses from OneDrive/Dropbox now respect
Retry-After (capped at 60s) instead of hammering.
- Per-source rate-limit state persisted across app restarts.
- Resumable downloads via HTTP
Range verified end-to-end.
Sync queue
sync_queue gains max_attempts (default 12). Jobs that hit the cap move to terminal "failed" instead of retrying forever.
- Daily housekeep purges consumed queue + pairing rows older than 30 days. Also runs at startup.
Per-photo visibility
sync_state.status column added — push + pull workers now populate pending/synced/failed for future UI.
Mostly invisible foundations — these defend against cloud rate limits and unbounded queue growth on long-offline installs.
v0.8.1
2026-06-16
AI throughput + duplicate scan at scale
AI pipeline
- AI worker pops 20 jobs per cycle and runs them in parallel via Rayon. ~6× throughput at 500k photos.
- CLIP HNSW index built on a background thread — Library page paints in <1s even on 500k-embedding libraries.
- Job settlements bulked into one transaction per batch.
Duplicate detection
- Pigeonhole bucketing replaces the O(n²) nested-loop pHash compare. At 500k photos: minutes → seconds.
- Union-find groups transitively similar photos in a single pass.
IPC bandwidth
- New
query_photo_ids endpoint returns just Vec<i64>. PeoplePage / ThingsPage send 50× less data when enqueuing AI jobs.
No DB schema changes. Best felt on libraries past 100k photos with AI enabled.
v0.8.0
2026-05-19
Scale, cache, and backup overhaul
Scale
- Library page now uses cursor pagination — opens instantly on libraries of any size.
- Album detail uses the same cursor endpoint; the old 5,000-row materialization is gone.
- Migration 14: partial indexes for trash, album sort, faces, EXIF GPS.
- Watcher debounce: 1,000 files dropped into a watched folder → ~1 scan, not 1,000.
list_geo_points + on_this_day use the read pool with bounded limits.
- WAL
autocheckpoint=1000 + 64 MB journal_size_limit.
PRAGMA quick_check on startup logs DB issues instead of failing silently.
Cache
- New
thumb_lru SQL index replaces directory-walk eviction. O(log n) instead of scanning millions of files.
- Configurable cache cap (500 MB – 200 GB). Default raised from 500 MB to 5 GB.
- Per-photo
cache_epoch — rotating one photo no longer wipes the whole library cache.
Backup & portability
- New Settings → Backup tab.
- Export library backup: ZIP with DB (after WAL checkpoint TRUNCATE) + XMP sidecars + manifest of every photo SHA.
- Restore from backup: pick a ZIP + your photos folder; we verify originals and copy the DB into place.
- Move library to a new drive: tell us the new root, we keep the old paths so existing references keep working.
library_check_online lets the UI show a "drive disconnected" banner instead of hanging.
Major version bump (0.7 → 0.8). DB migrates automatically. Best felt on libraries with 50,000+ photos or external-drive setups.
v0.7.2
2026-05-19
Mobile companion handshake
- Real X25519 ECDH + HKDF-SHA256 key derivation between desktop and the new Android companion app.
- New LAN sync endpoints for mobile:
/sync/pair/complete, /sync/ping, /sync/manifest, /sync/exists, /sync/upload, /sync/search, /sync/thumb/{sha}, /sync/file/{sha}.
- AES-256-GCM "envelope" wire format (12-byte nonce + ciphertext + tag, base64) matches the mobile app byte-for-byte.
- mDNS advertisement now publishes
hub_mode in TXT records so mobile companions can auto-prefer always-on machines.
- PhotoSphere Mobile 0.1.0 APK available on the Download page — sideload to pair with this desktop.
First pairing with v0.7.2 rotates the desktop's sync key (legacy SHA-256 stand-in is replaced by real X25519). Any existing desktop-to-desktop pairings will need to re-pair once.
v0.7.1
2026-05-12
In-app release notes
- New What's New tab in Settings — every future release is listed there, with the current version highlighted.
v0.7.0
2026-05-12
Performance pass — competing with Google & Apple Photos
Faster queries & scrolling
- New SQLite indexes for library timeline, album/tag joins, and face clusters — filtered queries are dramatically faster on large libraries.
count_photos now uses a real COUNT(*) instead of materializing every row.
- Read connection pool lets multiple queries run concurrently with the writer (WAL).
- Grid payload trimmed: photo rows now send only the fields the UI renders, ~70% less IPC data.
- Cursor pagination so deep scrolling stays O(log n) regardless of page depth.
Snappier UI
- Thumbnail size now matches the rendered tile (xs/sm/md by zoom) — no more decoding 512px JPEGs for 80px tiles.
- Thumbnails pre-generate in idle waves of 200 instead of blocking on 600 up-front.
- Photo viewer preloads the ±2 neighbouring photos for instant arrow-key navigation.
- React Query caches IPC results — switching tabs no longer re-hits the backend.
- IndexedDB-backed thumbnail blob cache (500 MB LRU) eliminates re-scroll flicker.
Safer imports
- Scanner now commits photos in batches of 500 instead of one giant transaction. UI stays responsive during big imports, and a crash mid-import keeps everything already processed.
No new user-facing features in this release — pure performance work. Best felt on libraries with 10,000+ photos.
Older builds aren't publicly archived. Earlier private betas (0.1–0.6) tracked feature buildup; 0.7 is the first public-facing release.