github dannyvfilms/Floppy v26.11.12

50 minutes ago
Floppy v26 11 12 Release Desk

Changes since last release:

This is an unusually large Floppy update. The shared React interface has advanced considerably, the native app groundwork has moved forward, and I've spent much of the time since October 29 chasing down the unnecessary work that makes large self-hosted libraries feel slow. The result is a broad round of faster Home shelves, more predictable History and Statistics, better tracking and integrations, and a lot of fixes that make the UI feel like Floppy again.

The performance figures below are measured on controlled fixtures or specified installations, not guarantees of page-load speed on every server. Several measure server-side CPU rather than time spent waiting in a browser.

Highlights

  • A faster Home screen: Rebuild TV and anime shelves from compact show information instead of loading the entire tracking history; substantially cut the memory used by completed-season rows.
  • A more consistent React interface: Restore familiar Home, Search, Track, Collection, Calendar and detail-page behavior, with a systematic comparison against v26.10.29 across 86 pages.
  • Native-app foundation: Expand the shared APIs and layouts used by both web and the developing iOS/Android apps, including saved library views, bulk actions and detailed item screens. Native apps are not available for public testing yet.
  • Better History performance: Stop rebuilding years of History just to view one month, limit background warming to likely visits, and speed up filtered History scans.
  • More useful podcast tracking: Record individual podcast listens reliably; search with Podcast Index, pasted RSS feeds and Apple Podcasts links; repair the History edit-form opening behavior.
  • A more personal library: Save sidebar pins to your account, use library bulk actions and saved views, link Home row headings to their destinations, and reuse past tracking sources in the Track form.
  • More accurate tracking: Support simultaneous check-ins across different media types, better full-show rewatch progress, safer episode completion checks and repaired status/history caches.
  • Improved sync and imports: Honor users' TVDB preferences in Sonarr, avoid large-integration disconnect timeouts, improve Plex/Kodi scrobble identity, respect personal IGDB keys and fix IMDb ratings that were incorrectly treated as watched history.
  • Faster Statistics and less background disruption: Remove repeated Statistics processing, avoid pathological dense-library credit lookups, and have heavy maintenance back off during real interactive use without being stalled by scrobblers.
  • More resilient startup and database reads: Keep Floppy responsive during SQLite write contention, warm cold SQLite data, avoid pointless rewrites, and return an actionable retry response during startup instead of leaving the port silent.
  • Faster, safer delivery: Reuse verified migrated test databases, keep coverage work off Docker's publication path, strengthen React bundle verification and update vulnerable dependencies.

Performance Improvements — With Receipts

Home shelves and memory

  • Whole cold Home, 12 shelves, 10,000 shows: 96.5s → 32.1s CPU (about 67% less). The TV/anime shelves alone dropped 74.1s → 11.8s (about 84% less).
  • Model objects instantiated across Home: 543,689 → 169,427 (about 69% fewer); database queries: 2,531 → 1,430 (about 43% fewer). For TV/anime shelves, models dropped 442,253 → 67,991 (about 85% fewer).
  • Completed-season Home shelf, 10,000 shows: 17.1s → 6.2s CPU, traced Python memory 480 MiB → 118 MiB. At 2,500 shows, its traced peak fell 508 MiB → 33 MiB. This removes unnecessary decoding of large provider metadata.
  • Fresh Home load: 24 → 12 shelf requests (90 → 78 total browser requests). A separate Up Next benchmark improved 307ms / 29 queries → 196ms / 15 queries.

TV lists, Statistics and History

  • Cold TV time-left sorting, 2,500 shows: 7.2–7.5s → 1.8–2.4s CPU, tracker models 104,315 → 6,051 (94% fewer), traced Python peak 209 MiB → 28 MiB. At 10,000 shows the old SQLite path failed with too many SQL variables; the new path finished in 5.7–8.1s.
  • All 11 Statistics ranges: 6.04s → 4.84s CPU (20% less), 1,642 → 1,398 queries, with process RSS growth 109 MB → 90 MB; all 44 reference Statistics payloads were identical.
  • Cold filtered History spanning 2,000 days: 41s → 7s on the synthetic fixture.
  • History background warming, 3,650-day fixture: 193s → 1.4s CPU, 109,541 → 767 queries, and 19.7 MB → 151 KB of payloads. The estimated steady-state rebuild count for the fixture went from about 243 → 3 per day.
  • Cold monthly History index, 9,600-day fixture: 84–145ms → 7–8ms CPU, Python peak 1.7 MiB → 0.3 MiB.

Responsiveness, tracking and maintenance

  • Discover request during a deliberately held SQLite write lock: 1.64s → 0.11s, without skipping the response or changing its content.
  • Episode plays below the stored season count: 3 → 0 provider-cache reads; completion-boundary plays keep the safer lookup. No end-user latency claim is made for this micro-optimization.
  • Background task during a two-minute scrobbler session: 187s → 35s in a controlled trial, because noninteractive polling no longer holds maintenance off. During actual app use, maintenance now intentionally yields rather than competing with browsing.
  • Dense-library Top Talent query: In one affected SQLite installation, the former indexed query took 5.0s to retrieve 2,000 credit rows, while the new adaptive sequential path retrieved 200,000 rows in 0.964s; the Celery queues subsequently drained and affected pages recovered. These are different query strategies and row counts, not a directly comparable same-work speedup.
  • Local migrated test-database setup: 113.6s → 1.4s with 11,536 tests passing. GitHub Actions cache-hit improvements are not yet independently measured. A separate publication change removes coverage tracing from the critical path; automatic reuse of a PR's earlier green result remains opt-in and disabled until validated.

These are the final PR benchmarks (including #1943 and #1946), superseding some earlier experimental numbers. The Home work deliberately rejected a broad shared facts cache after testing showed it could make individual lazy shelf requests slower and use more memory.

What this means for daily use

Home should do substantially less work before it can fill a shelf, especially with a large TV library. History should stop doing an entire archive's work to display one month. Watching, browsing, importing and running background maintenance should interfere with each other less often. The shared React experience has also regained a number of details that made the previous interface comfortable to use.

I'm continuing to benchmark large libraries and compare outputs against the previous behavior rather than treating any optimization as successful merely because the code changed.

Known Issues

  • The native iOS and Android apps remain in development; this Docker/web release does not announce a public native-app test or launch.
  • Podcast History's pencil now opens the Track Episode form, but it does not yet provide a dedicated editor for the individual selected listen; that remains follow-up work.
  • Some PostgreSQL test fixtures can trigger an intermittent query-planner slowdown under unusual mid-test autovacuum conditions; it was reproduced against both the baseline and the optimized Home path. No production regression has been established, and the underlying query remains under investigation.

Installing & Updating

The canonical Docker image for Floppy is:

ghcr.io/dannyvfilms/floppy:latest

Existing Floppy installations using the legacy ghcr.io/dannyvfilms/yamtrack:latest image can move to the new image path, which continues to receive updates during the transition.

Coming from upstream Yamtrack? Please use the supported CSV import process rather than replacing your Yamtrack container image directly. Database migrations may not be reversible, so preserve your original database and test Floppy separately before migrating.

Back up your Floppy data before upgrading, especially if you're moving between older builds or using a large library. For installation methods, configuration and troubleshooting, see the README and deployment documentation.

About Floppy

Floppy is a free, open-source media tracker that started as something I wanted to use myself. It's grown into something much bigger thanks to the people using it, sharing ideas, reporting bugs, and contributing improvements.

My goal is to build a tracker that is useful, reliable and enjoyable to self-host. Floppy is independently maintained, uses AI-assisted development tools, and builds on the original work of Yamtrack and its contributors.

Community & Contributors

Thank you to @MangaValk, @zotabee, @cbrunie, @Tobechukwu-Njoku, @ghub-priv, @VictorVow and @daften for merged contributions in this release. Special thanks to first-time merged contributor @Tobechukwu-Njoku, and to everyone testing the React migration, reviewing the native work, reporting problems and sharing careful feedback.

The Discord has grown beyond 200 members, and Floppy is approaching 1,000 GitHub stars. I appreciate everyone who's made this project bigger than anything I initially planned.

Have an idea or found a problem? GitHub Issues is the best place to report it. You can also join the Discord community to discuss features, share your setup and help other users.

Support Floppy

If Floppy has become part of your routine, consider sponsoring its development on GitHub.

Sponsorships help me invest in the AI development tools and other resources needed to keep improving Floppy, responding to community feedback and building new features. Feedback, testing, issue reports and contributions are valuable support too.

Thank you for helping Floppy get this far. I really appreciate it!

Happy tracking!


Full Technical Changelog

The following pull requests were merged after the last published release. This mirrors the GitHub-generated release-note style; two entries (#1787 and #1789) are late promotion/CI work for v26.10.29, included for audit completeness.

What's Changed

  • Treat Plex episode tvdb:// ids as episode-level by @MangaValk in #1782
  • Find the API copy after a watch in the anime library by @zotabee in #1792
  • feat(listenbrainz): serve the token owner's stats/user rankings by @cbrunie in #1794
  • Make incremental sync reliable with opt-in bootstrap and snapshots by @dannyvfilms in #1805
  • Clear media runtime caches again after commit by @Tobechukwu-Njoku in #1810
  • Document which services support bidirectional sync by @dannyvfilms in #1826
  • Stop rating chips without a series graph from moving on hover by @dannyvfilms in #1770
  • Add Podcast Index, pasted RSS and Apple links to podcast search by @dannyvfilms in #1778
  • Let check-ins of different media types run side by side by @dannyvfilms in #1777
  • Suggest past sources on the Source field and fill it for more syncs by @dannyvfilms in #1776
  • Resolve personal provider keys during webhook processing by @Tobechukwu-Njoku in #1811
  • Decode PostgreSQL custom field values before filtering and sorting by @Tobechukwu-Njoku in #1812
  • Restrict the instance-wide TMDB proxy to superusers by @Tobechukwu-Njoku in #1813
  • fix(scrobble): preserve canonical TV episode identity by @ghub-priv in #1839
  • Fix IMDb rating imports without fabricating watched history by @ghub-priv in #1832
  • test(oauth): isolate credential caches between OAuth state tests by @ghub-priv in #1834
  • test(jellyfin): cover incomplete Stop playback grace period by @ghub-priv in #1835
  • Fix transient scrobble provider failures returning permanent 404 errors by @ghub-priv in #1833
  • build(ui): regenerate stale committed React bundles by @ghub-priv in #1840
  • test(library): cover game-platform filtering across SQL-paginated pages by @ghub-priv in #1836
  • fix(history): preserve music consistency and invalidate caches after commit by @ghub-priv in #1837
  • Preserve precise webhook playback event ordering by @Tobechukwu-Njoku in #1814
  • security: add bounded pinned HTTP transport for self-hosted integrations by @ghub-priv in #1838
  • docs: clarify native mobile status and link contributor guide by @dannyvfilms in #1868
  • ci: separate Docker publication gates from browser E2E regressions by @dannyvfilms in #1867
  • Batch season-episode list membership lookups by @Tobechukwu-Njoku in #1848
  • Quote interpreter path in entrypoint data-path tests by @Tobechukwu-Njoku in #1849
  • security(c08): migrate Jellyfin, Seerr, gPodder and Koito to pinned transport by @ghub-priv in #1852
  • fix(scrobble): reconcile duplicate Kodi and generic movie sessions by @ghub-priv in #1862
  • fix(kodi): verify series identity before recording TV episodes by @ghub-priv in #1863
  • Fix release quality gate contracts by @dannyvfilms in #1878
  • Scope IGDB ratings backfill to the tracking user's key by @dannyvfilms in #1882
  • Fix phone menu taps, carousel arrow and Home bundle by @dannyvfilms in #1880
  • Store sidebar pins on the account instead of localStorage by @dannyvfilms in #1883
  • Podcast listens as their own rows, plus the play lifecycle API (#1874) by @dannyvfilms in #1884
  • Fix backend defects from issue 1873 by @dannyvfilms in #1885
  • Keep SQLite startup admission working after a reboot changes the device number by @VictorVow in #1847
  • Sync local-only work: WeTrakr limit, Expo audit, diagnostic report, task logs, ISBN scope by @dannyvfilms in #1886
  • Restore the v26.10.29 Track modal layout in the shared React form by @dannyvfilms in #1887
  • Add library bulk actions, saved views and detail page API for native by @dannyvfilms in #1888
  • Add cross-platform verification rules and native screenshot tooling by @dannyvfilms in #1889
  • Fix #1876: IGDB backfill key scope and sidebar blanking on navigation by @dannyvfilms in #1890
  • Follow-ups to the issue 1873 backend fixes by @dannyvfilms in #1891
  • Fix web regressions found against v26.10.29 by @dannyvfilms in #1897
  • Give PUID ownership of the SQLite sidecar files by @dannyvfilms in #1903
  • ci: make React bundle integrity a reliable required check by @ghub-priv in #1854
  • Link Home row titles to their destination on web and Expo by @dannyvfilms in #1904
  • Hold the port during startup and cut redundant Home row work by @dannyvfilms in #1905
  • Integrate Expo parity while preserving polished Web screens by @dannyvfilms in #1910
  • Stop page loads waiting for SQLite's writer to save derived data by @dannyvfilms in #1921
  • ci: publish without coverage tracing, and reuse a PR's green test run for an identical tree by @dannyvfilms in #1917
  • perf(statistics): remove repeated work from the range aggregate by @dannyvfilms in #1913
  • Rank the TV time-left order from grouped facts by @dannyvfilms in #1915
  • Let a play skip the provider payload while below the stored episode count by @dannyvfilms in #1927
  • Upgrade krb5-libs in the image to fix the Trivy scan by @dannyvfilms in #1931
  • Keep the database warm and stop saves rewriting unchanged credits by @dannyvfilms in #1933
  • ci: reuse a really-migrated SQLite test database while its inputs are unchanged by @dannyvfilms in #1930
  • Bound cold History index reads and warm only the user's recent days by @dannyvfilms in #1936
  • Fix match: move cross-season plays correctly and reload afterwards; let empty seasons not block a provider move by @daften in #1935
  • Clear library view caches through one function by @dannyvfilms in #1937
  • perf(statistics): avoid pathological credit queries on dense SQLite libraries by @ghub-priv in #1864
  • Count a whole-show rewatch once only its last season is still open by @daften in #1925
  • Keep Sonarr sync on the user's TV provider and stop disconnect 504s by @dannyvfilms in #1940
  • Let the Floppy app and React pages hold back maintenance, not automation by @dannyvfilms in #1938
  • Upgrade soupsieve to clear dependency audit by @dannyvfilms in #1947
  • Open a form from a podcast episode's history pencil by @dannyvfilms in #1941
  • Rank Home's TV shelves from show facts instead of hydrated trackers by @dannyvfilms in #1943
  • Keep the show's provider blob out of season shelf scans by @dannyvfilms in #1946

New Contributors

Full Changelog: v26.10.29...v26.11.12

Don't miss a new Floppy release

NewReleases is sending notifications on new releases.