
A target that felt generous
When we started building SyncGallery, we chose a clear performance target: the app had to stay fast with 100,000 media files on a device. We wrote every algorithm with that number in mind and tested with libraries of roughly that size.
At the time, 100,000 files seemed generous. At 30 photos a day, every day, it would take about nine years to reach that total. We were confident no one would keep more than that on a phone.
Users proved us wrong
Shortly after the first release, we learned how wrong that assumption was. Real libraries were far bigger than our ceiling: years of camera archives, photos migrated from older phones and computers, and entire family collections stored on large memory cards. Many Android phones still accept 512 GB or even 1 TB memory cards—room for libraries many times larger than our original target.
The app did not suddenly fall over at file 100,001—performance limits are rarely that polite. Instead, operations that should feel instant took noticeably longer, and the experience kept getting worse as a library grew beyond the target. For people with the biggest libraries—arguably those who need a backup app the most—that was not good enough.
What changes at ten times the scale
Many shortcuts that are harmless at 100,000 files become problems at a million. The pattern is always the same: a cost quietly grows with the library.
- Holding everything in memory. A list of 100,000 entries fits comfortably in RAM. At ten times that size, multiplied across screens and caches, memory pressure causes stutter and, in the worst case, crashes.
- Rechecking every file when only a few changed. Re-examining the whole library because a handful of photos arrived is barely noticeable at 100,000 files. At a million, it can mean minutes of background work with no visible benefit.
- Updating the screen after every change. One update per processed file is unnoticeable in a small library. When changes arrive by the tens of thousands, it can freeze the interface.
- Letting caches grow forever. An unbounded cache eventually competes with the screens it was meant to speed up.
These are not exotic bugs. They are ordinary engineering decisions that stop working one order of magnitude later.
Rebuilding for one million
We raised the target to one million files and went back through the app with that number as the new bar. A few rules now shape everything we build:
- Keep memory use flat as the library grows. The heaviest list screens now load files from the database in windows instead of holding everything in memory. Large image caches are bounded, so they evict older entries rather than growing forever. This rollout continues screen by screen; it is the discipline we now build against, not a finish line we have crossed everywhere.
- Compare instead of rereading. Scans track what changed rather than reprocessing everything. When a cloud provider offers a change feed, we consume those changes instead of listing entire folders again.
- Never make the interface wait for the library. Heavy work runs behind the scenes in batches. Screen updates are combined so a burst of 10,000 changes does not trigger 10,000 redraws.
- Measure on real devices with real libraries. Profiling replaced guessing. The biggest wins came from places we would never have suspected without measuring.
Fast is a habit, not a milestone
The most important change was not any single fix. It was making the million-file question part of how we evaluate every new feature: What happens to this screen, scan, or cache when the library is ten times bigger than we expect?
Somebody will exceed whatever number we choose, and we would rather be ready this time.
If you have a huge library, this work was made for you. If SyncGallery ever feels slow with your collection, tell us—real libraries teach us more than synthetic benchmarks.