Photos does an enormous amount of work behind your back: indexing for search, detecting faces, classifying scenes, rendering thumbnails, uploading to iCloud. It tells you almost nothing about it. If you've ever wondered why Photos has been "still analysing" for three days, or why a keyword you added isn't searchable yet, the answers exist — scattered across a Core Data store, a private search index and the unified log. This gathers them onto one page, and just as importantly, tells you when something isn't knowable rather than inventing a plausible number.
What it shows
- Background job queue. Depth, mix by type and flags, age profile, and which photos have the most work outstanding.
- Analysis progress. Per-worker completion, from the one place in the database that genuinely records finished work.
- Search index. Size, coverage, and exactly which keywords Photos can't yet find.
- Can anything run? The Duet scheduler's verdicts from the unified log, plus which daemons hold the library — the usual answer to "why is nothing happening".
- Save-integrity check. Catches a specific corruption that silently breaks all editing in a library, and that a standard database integrity check reports as fine.
- Library census and write activity. Assets, faces, people, keywords, albums, resources, and every save Photos makes, with which subsystem made it.
Your library is never modified
This reads a database that's difficult to replace and impossible to un-corrupt, so read-only is enforced three independent ways, not promised once: mode=ro on the connection URI, PRAGMA query_only on the connection, and a SQLite authorizer that rejects every non-read action before a statement is even compiled. It ships with an executable test that issues real writes, checks each is refused, then clones a library, hashes every file, runs every collector, and re-hashes — comparing content, size, mtime and inode. An optional snapshot mode reads a copy instead, so nothing inside the library bundle is touched at all.
Screenshot
Quick start
macOS, Python 3.10+, a browser. No dependencies — standard library only, no pip install, no build step.
- Clone the repository:
git clone https://github.com/gerardkieffer/photos-dashboard.git - List the Photos libraries it can find:
python3 photo_dashboard.py --list - Start it:
python3 photo_dashboard.py - Open
http://localhost:8787/— it binds to localhost only.
If a library shows as BLOCKED, that's macOS's own file-access control (TCC), not a bug — the documentation covers granting it. A library on an external volume needs no permission at all.
Further information
- Photos Library Dashboard is open source under the MIT licence; the code is available on GitHub, including the full documentation and the measured technical reference the collectors are built from.
- Verified against
LibrarySchemaVersion5001 (macOS Sequoia / Tahoe). It reads a private, undocumented schema that Apple can change at any time — nothing is hard-coded, but other versions are untested. - Reading a library in your home folder needs Full Disk Access; the unified-log panels need
log show, which is slow and occasionally empty.