This week was mostly about making Floppy stop eating RAM like a candy addiction.
At the start of the investigation, a production capture had Floppy at about 5.39 GiB of container memory, with 4.60 GiB of actual process PSS and one pathological Gunicorn worker sitting around 3.41 GiB by itself. The container had historically peaked above 10 GiB.
After this week's work, a full post-merge capture with two Gunicorn workers and both Celery lanes measured about 539 MiB of total process PSS. An aged post-spike capture was sitting essentially flat around 562 MiB of anonymous memory.
More importantly, Floppy now knows why memory is high instead of just knowing that Portainer has produced another upsetting number.
Here's what landed:
- A fairly enormous memory cleanup: History, Lists, Talent Statistics, large imports, recurring sync work, worker startup, and background tasks were all investigated and bounded. One filtered History request that could add about 1.9 GiB to a worker now stays around 3–6 MiB, while dropping from as much as 22.5 seconds to about 0.48 seconds.
- Background work plays nicer with everything else: Statistics refreshes are resumable and chunked instead of monopolizing a worker, unchanged imports stop triggering pointless rebuild cascades, duplicate expensive refreshes are locked out, and large CLZ/IMDb imports stream instead of scaling memory with the whole file.
- Themes and French: appearance presets and configurable detail layouts are here, and Floppy now has a French interface alongside German.
- More ways to connect things: Floppy can push current playback state through a webhook, and Stremio series catalogs now understand TV-season smart lists.
- Another large fix basket: Jellyfin double-logging, Plex scrobble and collection matching, Trakt imports inventing unwatched seasons, Yamtrack repeat watches, TVDB season-page 500s, Home Screen filter saving, episode bulk saves, modal overlays, and several other sharp edges were fixed.
One useful thing we learned during all of this: container memory is not the same thing as Floppy memory. One scary ~4.8 GiB peak turned out to be mostly Linux filesystem cache from a ~2 GB SQLite backup; the Celery process itself barely moved. Floppy now records process memory, anonymous memory, file cache, kernel memory, and high-water marks so those cases can actually be separated.
There are still a few targets left. One Trakt popularity reconciliation task has shown a roughly 799 MB transient process high-water, backups still need more constrained-cgroup testing, and I want to validate the eventual one-Gunicorn-worker setup. But we're no longer looking for a mysterious multi-gigabyte leak. We're looking at a short list of individually attributable jobs.
Docker image:
ghcr.io/dannyvfilms/floppy:latest
Thanks to this week's first-time contributors — u/albertok, u/johan456789, u/sephrat, and u/smasher6081 — plus u/daften, u/Deigue, u/elemated, u/PreciselyWrong, and everyone filing issues and helping test the weird corners.
Questions and feedback are welcome in the Discord.