Self-hosted service
Tautulli/Tautulli avatar
Tautulli/Tautulli

Tautulli: three release branches, and three dependencies manually patched for Python 3.13

A Python based monitoring and tracking tool for Plex Media Server.

6,640 stars639 forksPythonGPL-3.0

At a glance

What is it?
Tautulli is a Python web application for Plex Media Server monitoring, analytics and notifications. It publishes master, beta and nightly branches, and its pinned requirements file has three entries commented out as manually patched.
Who is it for?
Adopt Tautulli if you run Plex and want per-user watch history, library statistics and configurable notifications, since that is the whole product and it needs no separate web server. Run the master branch unless you are testing, because nightly has no versioned releases and only tracks commits since the latest release.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • Tautulli/Tautulli6,640 ★ · +49
Star history
Repository2026-09-232026-11-14
Tautulli/Tautulli6.6k6.6k

49 Stars in the last 52 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

Three branches times four packaging formats is a twelve-way release matrix

The installation section of the README is a table, and the table is the interesting part. There are three branches, master, beta and nightly, and a Release row of badges for each.

What each branch means is legible from the labels. On master, Release is a version tag with a release date. On beta, Release includes prereleases, alongside a commits-since badge. On nightly, there is no versioned release badge, only a last-commit badge and a commits-since badge.

So nightly has no versioned release, which makes sense for a branch whose purpose is to be ahead of a release.

The README's badges point to Docker Hub under tautulli/tautulli and to GitHub release downloads. The Python requirement is stated only as a badge, python >= 3.11, with no prose explanation.

One thing worth noticing about the default branch: it is nightly, not master. The repository's default branch is the one ahead of releases, which is a deliberate choice and a useful one to know about, because it means browsing the repository by default shows you work in progress rather than the code behind the latest tag.

Installation itself is delegated to a set of Installation Guides rather than reproduced in the README.

Three dependencies are commented out and manually patched for Python 3.13

requirements.txt pins every dependency to an exact version, which is the right choice for an application rather than a library. The tail of the file is where the interesting information is, and it is three commented lines:

code
# facebook-sdk==3.1.0  # Manually patched for Python 3.13
# gntp==1.0.3  # Manually patched for Python 3.13
# git+https://github.com/JonnyWong16/infi.systray.git@develop#egg=infi.systray

Two of them, facebook-sdk and gntp, are pinned versions with the same note attached: manually patched for Python 3.13. The third is different in kind. infi.systray is not installed from the package index at all but from a develop branch of a fork, on the egg fragment syntax.

Reading these together gives you a fairly precise picture. Facebook and gntp (Growl) notifications are integration features rather than core ones, and the project's response to Python 3.13 was to patch them manually rather than install them from the declared dependency set. The systray dependency points the other way: it was taken from a fork's develop branch, which is a live dependency on someone's unpublished branch.

That has two consequences. If you deploy Tautulli yourself, you have to decide what to do about those three, and the file does not tell you, because the answer depends on whether you use the Facebook or gntp notification integrations and whether the systray fork's develop branch still resolves. And if you are evaluating the project's Python 3.13 support, this is the place to look, because it says the support is partly carried by patches the project does not ship through the index.

The file also uses environment markers elsewhere. rumps is listed as rumps==0.4.0 with the marker platform_system == "Darwin", so it is installed only on macOS. That is a platform-specific dependency declared correctly, and it is the kind of detail that tells you the macOS path is a supported configuration rather than an accident.

The pinned dependency list doubles as a list of Tautulli's integrations

Reading requirements.txt as a feature list is more informative than reading the feature bullets, because a pinned dependency is a thing the project actually calls.

The Plex relationship is plexapi==4.18.3, the Plex API client library. Everything Tautulli knows about your server, it learns through that, which means the compatibility surface between Tautulli and your Plex server runs through the version of plexapi in this file.

The web layer is CherryPy, with cheroot and cherrypy-cors alongside it. CherryPy is the application server, cheroot is its HTTP server, and cherrypy-cors handles cross-origin headers. That combination is what makes the feature bullet about easy configuration setup with no separate web server required true: Tautulli serves itself, so there is no nginx or Apache in the picture.

Template rendering is Mako, HTML parsing is beautifulsoup4 with html5lib and bleach, and the charting is Highcharts according to the feature list. Structured data handling is xmltodict and requests with urllib3 and certifi underneath it.

Then there is the notification and metadata cluster, and this is the longest tail. paho-mqtt for MQTT, python-twitter for posting to Twitter, cloudinary for image hosting, ga4mp which is an audience analytics library, musicbrainzngs for music metadata, ipwhois for IP address information, PyJWT for tokens, and arrow plus tzlocal for date and timezone handling. apscheduler is at the top of the file, which is the scheduled job runner that makes notifications for recently added media fire without anyone watching.

So a fair summary of the dependency set is: a Plex API client, a self-hosted web stack, a template and charting layer, an HTML sanitising path, a scheduler, and roughly eight outbound integrations. That last group is what to look at if you care about what leaves your server.

There is also requirements-dev.txt as a separate file, so development dependencies are kept apart from runtime ones rather than mixed in.

PlexPy.py and a plexpy directory are still in the root, which is a rename left visible

The repository root contains both Tautulli.py and PlexPy.py, and both lib/ and plexpy/ directories. Tautulli was previously called PlexPy, and the old name has not been removed from the tree.

The README explains the lineage rather than the rename. The project is based on code from Headphones and from PlexWatchWeb, both linked by name.

Whether that is a problem depends on what you are doing. For a user running the application it is cosmetic. For anyone reading the code or writing against it, it means the names in the tree do not all match the project name, and searching for plexpy will find both historical and current locations. It is also a useful signal about the project's age and lineage, because a codebase that started as a Plex notification tool and became a full analytics dashboard has accumulated the vocabulary of both.

Other root entries describe the shape of the project more directly. There is a Dockerfile and a .dockerignore for the container path, a snap/ directory for the Snapcraft package, package/ for packaging, init-scripts/ for service startup, contrib/ for contributed extras, data/ for the application directory, and tests/ with both pytest.ini and pylintrc at the root, so testing and linting are configured at the top level rather than inside the test directory.

There are start.sh and start.bat, which is the direct evidence for the no-separate-web-server claim: those are the entry points, and they start the bundled server. The repository also carries SECURITY.md, CONTRIBUTING.md, CHANGELOG.md and API.md, and an API.md at the root implies the application exposes an HTTP API of its own rather than only a web interface, which matters if you want to script against your own monitoring data.

The feature list is a server administrator's dashboard, not a media library tool

The feature list is worth reading as a statement about what problem this solves, because it is not about the media. Not one bullet is about finding, playing or organising content.

The interface bullets come first: responsive web design viewable on desktop, tablet and mobile web browsers, and themed to complement Plex/Web. Being themed to complement rather than to replace is the positioning, and it is why the project is a companion rather than a Plex replacement.

Then the monitoring: monitor current Plex Media Server activity, and top statistics on the home page with configurable duration and measurement metric. The configurability of both the duration and the metric is the detail that matters, because it means the home page answers different questions depending on how you set it rather than showing one fixed set of numbers.

Notifications get one bullet: fully customizable notifications for stream activity and recently added media.

Then the historical and per-user layer, which is the bulk of the list. Global watching history with search, filtering and dynamic column sorting. A full user list with general information and comparison stats. Individual user information including devices IP addresses. Full sync list data on all users syncing items from your library.

The library layer is complete library statistics and media file information, rich analytics presented using Highcharts graphing, and content information pages.

Put together, that is a tool for someone who wants to know who watched what, how much, on what device, and who is sharing and syncing what. That is a different question from what is in the library, and it explains why the project coexists with Plex rather than replacing any part of it.

What it cannot tell you, and what it needs from Plex to tell you anything

Four limits, each of which follows from the architecture rather than from a missing feature.

It reports on Plex, it does not manage Plex. There is nothing in the feature list about adding, editing or removing media, so if your problem is library curation this is the wrong tool and you want Plex's own library tools instead.

Its data comes from Plex, so it is only as good as what Plex records. Watch history, user statistics and device addresses are all things Plex has to have observed. A play that Plex did not record does not appear here, and there is no second source to reconcile against.

It measures consumption, not the network or the host. Nothing in the list covers transcoding load, disk I/O, request latency or the machine Plex runs on. Those are different monitoring problems and need different tools, and the name can mislead you into thinking this is a server monitoring system rather than a usage analytics one for one specific application.

And it is a Python application with pinned dependencies and, in three cases, patched or forked ones. That is a maintenance surface. The Python floor is 3.11, the pins are exact, and the commented lines in requirements.txt mean a clean install on a new Python version is not simply a matter of satisfying the file.

For evaluation, the shortest useful sequence is to run it against a server you already use for a week and look at the per-user history before deciding whether the notifications are worth configuring. The history is the part that has to be genuinely useful on its own; if it is not, the notification integrations will not rescue it.

On that note, the notification integrations are where the outbound traffic goes. MQTT, Twitter, cloudinary, the audience analytics library and the music metadata lookup are all dependencies in the same file as the Plex client, which is a reminder to enable the ones you want rather than all of them.

Editorial conclusion

Adopt Tautulli if you run Plex and want per-user watch history, library statistics and configurable notifications, since that is the whole product and it needs no separate web server. Run the master branch unless you are testing, because nightly has no versioned releases and only tracks commits since the latest release. Read requirements.txt before you pin, because the dependency set is fully pinned to exact versions and three packages are commented out as manually patched for Python 3.13, which tells you the Python 3.13 story is handled outside the package index. And note it derives from PlexWatchWeb and Headphones, and the plexpy/ directory and PlexPy.py still sit in the root: this codebase carries its own history, and that is worth knowing before you file an issue against something that looks like leftover naming.

Frequently asked questions

What is Tautulli and what does it do?

It is a Python based web application for monitoring, analytics and notifications for Plex Media Server. It monitors current server activity, provides global watching history with search and filtering, a full user list with comparison statistics, per-user device IP addresses, complete library statistics, and analytics presented using Highcharts. It also sends customizable notifications for stream activity and recently added media.

How do I install Tautulli?

The README points to its Installation Guides on the wiki, and its badges link to a Docker image on Docker Hub as tautulli/tautulli and to GitHub release downloads. The project requires Python 3.11 or newer, and because Tautulli serves itself there is no separate web server to configure.

What is the difference between the master, beta and nightly branches?

master carries versioned releases with a release date. beta carries prereleases, with a badge counting commits since the latest release. nightly has no versioned release badge, only last-commit and commits-since badges. The repository default branch is nightly, so browsing by default shows work ahead of the latest release.

Does Tautulli support Python 3.13?

Partly through patches rather than through the package index. requirements.txt is fully pinned, and three entries are commented out: facebook-sdk and gntp, both noted as manually patched for Python 3.13, and infi.systray, which is installed from a develop branch of a fork rather than from the index. rumps is also declared with a platform_system == "Darwin" marker so it installs only on macOS. If you deploy this yourself, those three need a decision.

Official sources

  1. License: GPL-3.0
  2. Project website
  3. README
  4. Releases
  5. Tautulli/Tautulli on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/tautulli-tautulli.svg)](https://hysenlabs.com/projects/tautulli-tautulli)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/tautulli-tautulli.svg)](https://hysenlabs.com/projects/tautulli-tautulli)

Was this useful?