# Reclaimerr deletes what your media library no longer needs, under rules you write

> Reclaimerr is a Python and Svelte application that scans Jellyfin, Plex and Emby libraries, finds items eligible for removal under rules you define, and routes the final action back through the right server, with protection states, approval flows and optional move instead of delete. It suits a self-hosted library that has grown past what a manual sweep can handle, and it is a tool that can delete your media, so the schedule and the protections are the parts to read first.

**jessielw/Reclaimerr** — https://jessielw.github.io/Reclaimerr/ - Automatically reclaim space in your media library using customizable rules. Integrates with Jellyfin, Plex, and Emby (any or all of them) to analyze and manage your content. Functions similarly to Seerr (in reverse), providing efficient media cleanup

- Repository: https://github.com/jessielw/Reclaimerr
- Stars: 569 · Forks: 12
- Language: Python
- License: GPL-3.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/jessielw-reclaimerr

## Reclaimerr is the mirror image of a request tool

The project description puts the idea in one line. It functions similarly to Seerr, in reverse, providing efficient media cleanup, so the mental model for anyone who has used a request management tool is the right one. A request tool collects asks for content that is not there, and this tool collects candidates for content that should not be there. The pipeline in the readme is short: Reclaimerr scans media libraries for eligible items, tracks protection and deletion requests, and routes the final action through the appropriate service. The routing to the appropriate service is the detail that matters, because with three media servers configured, a delete has to land on the server that actually holds the file, and the tool keeps that mapping rather than assuming one library.

## Three media servers, and Radarr and Sonarr alongside them

The capability list names Jellyfin, Plex and Emby, and says any or all of them, which is the point of the design. A self-hosted household with a Plex server for the living room TV and a Jellyfin server for the rest of the house is a common arrangement, and the rules you write should not have to be rewritten per server. Integrates with Radarr and Sonarr when configured, and the recent release history shows the current shape of that integration, with 0.5.7 titled as Sonarr v5 support. The distinction between the two is worth understanding. The media servers own the library and the files, and Radarr and Sonarr own the request and acquisition side, so an item Reclaimerr considers eligible may still be something an arr wants to re-acquire, and the presence of both in the same project is a design decision about how a cleanup tool should treat a library that is still being managed by an automated acquisition stack.

## Rules produce candidates, and the rules are the product

The capability list says it scans candidates using your reclaim rules, and the preview screenshots show a rules screen and a rule node screen, so the rule system is a visual object rather than a configuration file. That is the main design decision in the project, and it cuts both ways. A graphical rule builder is far more approachable than a query language for the person who owns a media library, and the screenshots show separate screens for movies, series and reclaim candidates, which suggests the rule tree is evaluated per media type. The risk is that a rule you can build visually is a rule you have to reason about, and since the rules drive deletion, the review step is the safety mechanism. A rule that matches too broadly does not produce a list you skim, it produces files that are gone.

## Protection, pending requests and approvals sit between a rule and a delete

Three things stand between a matching candidate and an actual deletion. The readme says the tool respects protection, pending requests, and approval flows, which is the difference between a script that deletes and a tool you can leave running. Protection is a state on the item itself, so you can mark something as kept and the rules will not override it. Pending requests cover the case where a user has asked for a title that is present but marked for reclaim, so the request has to be resolved before the deletion proceeds. Approval flows put a human in the loop, and the readme mentions a small model checking actions against rules in the Open Dot project rather than here, so in this project approval is a configured flow rather than an inferred one. The three protections together are what make scheduled automatic cleanup deletion a defensible thing to switch on.

## Move instead of delete is the setting to try first

The capability list includes can move instead of delete when configured, and that is the single most useful line in the readme for anyone evaluating a tool that can destroy a media library. The two behaviours are configured separately, and the quick start explicitly says to review the task schedule before enabling deletion, which suggests the author knows the failure mode is a rule set running unattended against real files. Moving gives you the same reclamation of space, since the readme's own framing is automatically reclaim space in your media library, but with a recoverable state, because a moved file can be moved back. A tool like this has a second mode in practice, and it is the one to run for a season before trusting the first.

## A FastAPI backend, a Svelte frontend, and a database that is yours

The stack is legible from the repository layout and the packaging. The backend is FastAPI served by granian, with SQLAlchemy over an async driver, Alembic for migrations, APScheduler for the scheduled tasks, and argon2-cffi, pyjwt, authlib and cryptography for the account and session layer. slowapi provides rate limiting, tenacity handles retries against remote services, apprise sends notifications, and semver and pyjwt sit alongside. The project targets Python 3.11 to 3.14, uses hatchling as the build backend, and ships three Python packages from the tree, backend/core, backend/api and backend/services. The database is aiosqlite, which means the state is a local SQLite file rather than a server, and the repository carries an alembic.ini and a uv.lock. The frontend is Svelte, built with Vite inside the container image, and there is a separate desktop build packaged with PyInstaller, pystray and platformdirs.

## The container image pins the dependency versions on purpose

The Dockerfile is worth reading because of one comment. The backend base image is python:3.13-slim with uv copied in from a pinned ghcr.io/astral-sh/uv image, and the install step exports the exact versions from uv.lock into a requirements file and installs them with uv pip install, with the comment explaining that it installs the exact versions from uv.lock so new upstream releases cannot break the image. The frontend is a separate node:25-alpine3.22 build stage whose output is copied into the API image, the application port 8000 is exposed, and the container is started with granian on the ASGI interface with one worker. The entrypoint runs as a non-root user through gosu, and the image creates the data directories for the database, logs and static avatars. The same pinned approach shows up in the Python project metadata, where the dependencies carry upper and lower bounds rather than being open ended.

## Where Reclaimerr is the wrong choice

The first wrong case is a streaming library, since the retention policy is set by the provider and there is nothing for a cleanup tool to reclaim. The second is a library you actively curate, where the value of an item is not captured by a watch-history rule, and the people who know why a season exists are not the people writing the rules. The third is a small library, because the effort is in writing and testing rules, and a hundred items do not need a scheduler. The fourth is a setup with no second server and no arr integration, where the whole multi-server routing and request-awareness machinery has nothing to do, and you would be better served by a one-off script. The fifth is an environment where a Python 3.11 to 3.14 service, a Node build stage and a SQLite file is more moving parts than you want next to your media server, and where a scheduled job that can delete files needs to be a component you are willing to be woken up about.

## Conclusion

Self-hosted library operators whose Jellyfin, Plex or Emby installs have accumulated unwatched or duplicate media are the people Reclaimerr is for, and the fact that it can move rather than delete, and that it honours protection states and pending requests, is what makes it safe to run on a schedule. It is the wrong tool for a streaming service library, since the service sets the retention rules, and it is the wrong tool if you want a one-off tidy-up, because the work here is in writing rules rather than in pressing delete. Check three things before you enable any deletion: that the main server is set correctly when you run more than one, because the readme makes that a separate step from connecting a server, that the reclaim rules you write reflect what you actually want kept, since the rules are scanned to produce candidates rather than a list you pick from, and that you have tested the move path before you turn on automatic cleanup deletion, because the two behaviours are configured separately. The licence is GPL-3.0, the newest release is 0.5.9 from 2026-10-19, and the last push was on the same day.

## FAQ

### Which media servers does Reclaimerr support?

Jellyfin, Plex and Emby, any or all of them at once. It also integrates with Radarr and Sonarr when configured, and the 0.5.7 release added Sonarr v5 support.

### How do I start using Reclaimerr?

Install it with Docker, the desktop build or from source, connect at least one media server, set one server as the main server when you have several configured, and then review the task schedule before enabling deletion.

### What stops Reclaimerr deleting something I want?

The readme lists three safeguards: the tool respects protection, respects pending requests, and supports approval flows. It can also be configured to move files instead of deleting them, and automatic cleanup deletion is a separate setting you enable deliberately.

### What is Reclaimerr built with?

A FastAPI backend served by granian with SQLAlchemy and Alembic, APScheduler for scheduled tasks, and a Svelte frontend built with Vite. The project requires Python 3.11 to 3.14, uses hatchling as the build backend, and ships a desktop build packaged with PyInstaller and pystray.

### Why does the Reclaimerr Docker image pin dependency versions?

The Dockerfile exports the exact versions from uv.lock into a requirements file and installs them with uv pip install, with a comment explaining that this is done so new upstream releases cannot break the image. The image also runs the application as a non-root user through gosu.

## Sources

- [Issues](https://github.com/jessielw/Reclaimerr/issues)
- [jessielw/Reclaimerr on GitHub](https://github.com/jessielw/Reclaimerr)
- [License: GPL-3.0](https://github.com/jessielw/Reclaimerr/blob/main/LICENSE)
- [README](https://github.com/jessielw/Reclaimerr/blob/main/README.md)
- [Releases](https://github.com/jessielw/Reclaimerr/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/jessielw-reclaimerr
