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.