Jellystat: self-hosted Jellyfin statistics with Docker and Postgres
Jellystat is a free and open source Statistics App for Jellyfin
At a glance
- What is it?
- Jellystat is an MIT-licensed statistics app for Jellyfin that logs sessions and watch history into Postgres. The README warns the project is paused for a ground-up rebuild, so adopt it with that in mind.
- Who is it for?
- Adopt Jellystat if you already run Jellyfin and Postgres, want session logging and per-user watch statistics, and can accept a project whose README says it is paused for a ground-up rebuild. Do not adopt it if you need multi-server support, a responsive UI, or a maintainer who is actively shipping features.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 6 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Jellystat solves for Jellyfin operators
Jellyfin itself tells you what is playing right now. It does not give you a durable record of who watched what, when, and for how long across libraries and users. Jellystat fills that gap: the README lists session monitoring and logging, statistics for all libraries and users, watch history, user overview and activity, watch statistics, backup and restore of data, auto sync of library items, and integration with a Jellyfin statistics plugin. The audience is a self-hoster running Jellyfin for a household or a small group, who wants the kind of per-user viewing report that Plex users get from Tautulli. The README's own framing is blunt: "This project is still in development - expect some weirdness." It is a statistics companion, not a media server, and it assumes you already have Jellyfin running somewhere it can reach.
How Jellystat stores and serves your watch data
The architecture visible in the repository is a two-part Node.js application backed by Postgres. The frontend is React with Vite and MUI; package.json shows the build script as vite build and the production entry as cd backend && node server.js. The backend uses Express, knex and pg-promise to talk to Postgres, jsonwebtoken for authentication, node-cron for scheduled work, and multer for uploads. The Dockerfile is a two-stage build on node:26-bookworm-slim: the first stage runs npm install and npm run build, the second copies the result and starts /entry.sh. The compose file pairs the app container with a postgres:18.1 container named jellystat-db, and the app reaches it by hostname through POSTGRES_IP. Two named volumes matter: postgres-data holds the database, and jellystat-backup-data is mounted at /app/backend/backup-data, which is where the backup and restore feature writes. Sessions are logged into Postgres, and the statistics pages are queries against that store. Nothing in the README describes a separate analytics engine or an external time-series database, so the size of your Postgres volume is the practical ceiling on how much history you keep.
Installing Jellystat with docker compose
The repository ships a docker-compose.yml, and the README's environment variable table defines what the app needs. Six variables are marked REQUIRED: POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_IP, POSTGRES_PORT, JWT_SECRET and TZ. A minimal compose file based on the one in the repository looks like this, with the placeholder values replaced by your own. Note that the shipped file leaves JWT_SECRET empty and sets TZ to mytimezone, so both need editing before the stack is useful.
First run: setup and the port question
The compose file publishes 3000:3000, and the Dockerfile EXPOSE 3000, which is the answer to the most common question about this project. The container healthcheck hits http://localhost:3000/auth/isconfigured, so the app exposes an endpoint that reports whether initial setup has been completed. On first load you go through a setup step that creates the username and password used for login. If you lose those credentials, the README provides an escape hatch: setting both JS_USER and JS_PASSWORD gives a master override, and the table notes that both are required for it to work. That is worth configuring before you need it, because without it a forgotten password means working directly against the database. The other variable to set deliberately is TZ, which the README marks required and expects in the tz database form, for example Etc/UTC or Europe/Paris. Session timestamps and any cron-driven jobs depend on it being right.
Where Jellystat is the wrong tool
The README carries a project update that should shape any adoption decision. The maintainer writes that bugs and issues keep piling up, that this was one of their first Node.js projects, and that they have decided to rebuild Jellystat from the ground up with a new backend language, a new frontend and possibly a different database provider. The update states that for a while the project is not going to be updated, with only occasional fixes for major bugs that are easily reproduced. So the honest position is this: the last push was on 2026-09-26 and releases shipped through 2026-09-08, but the maintainer's own stated plan is a pause. If you need multi-server support, note that it appears under Required Development rather than Current Features, so it does not exist yet. Responsive UI is also listed as still required, which means the interface is not built for phone screens. Security testing and more validation and error handling are likewise on the to-do list. If any of those are hard requirements for you, Jellystat is the wrong choice today.
Jellystat against Tautulli and Tracearr
The obvious comparison is Tautulli, which does for Plex what Jellystat does for Jellyfin. The difference in approach is mostly about where the data lives. Tautulli is a Python application with its own SQLite database and a long history of releases; Jellystat is a Node.js app that requires you to run and maintain Postgres alongside it. That is more operational surface, and it is also why the compose file ships a healthcheck on the database and a depends_on condition of service_healthy: the app cannot start before Postgres is ready. In exchange, Postgres gives you a store you can query, back up and move with standard tooling, and the jellystat-backup-data volume gives the app its own export path. Tracearr also appears in search traffic as a comparison point, but the README does not mention it, so there is nothing in this material to compare against. If you already run Postgres for other services, the extra container is cheap. If you do not, Tautulli's single-file database is the simpler deployment.
Licence, maintenance and upgrade cost
Jellystat is MIT licensed, which is permissive: you can use, modify and redistribute it, including in commercial settings, provided the licence and copyright notice are preserved. This is not legal advice, and the LICENSE file in the repository is the authoritative text. The maintenance picture is the part that needs care. Releases arrived at a steady cadence through 2026, with 1.1.10 in April, 1.1.11 in June and 1.1.12 in September, and the last push was on 2026-09-26. But the README's project update says the rebuild is coming and that updates will stop for a while. Upgrading means pulling a new image tag and letting the app run against your existing Postgres schema, and the README documents no migration procedure, so the upgrade path for a schema change is not described anywhere in this material. Backups matter more than usual here: the compose file maps jellystat-backup-data to /app/backend/backup-data, and the README lists backup and restore as a feature, so use it before any image change. If the rebuild lands with a different database provider, as the update suggests is possible, your existing Postgres data may not carry across, and nothing in the README commits to a migration path.
Editorial conclusion
Adopt Jellystat if you already run Jellyfin and Postgres, want session logging and per-user watch statistics, and can accept a project whose README says it is paused for a ground-up rebuild. Do not adopt it if you need multi-server support, a responsive UI, or a maintainer who is actively shipping features. Before deploying, verify three things: that JWT_SECRET and TZ are set in your compose file, that your Postgres instance is reachable at the POSTGRES_IP you configure, and that the jellystat-backup-data volume is mapped so backup and restore has somewhere to write.
Frequently asked questions
What port does Jellystat use?
The compose file publishes 3000:3000 and the Dockerfile exposes port 3000, so the web interface is on 3000 by default. The container healthcheck also queries http://localhost:3000/auth/isconfigured.
How do I install Jellystat with Docker?
The repository provides a docker-compose.yml that starts a postgres:18.1 container named jellystat-db alongside the cyfershepard/jellystat:latest image. You need to set POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_IP, POSTGRES_PORT, JWT_SECRET and TZ in the environment block before starting the stack.
What is Jellystat and what does it do?
Jellystat is a free and open source statistics app for Jellyfin. According to the README it provides session monitoring and logging, statistics for all libraries and users, watch history, user activity and watch statistics, plus backup and restore of data.
What can I use instead of Tautulli for Jellyfin?
Jellystat is the Jellyfin equivalent in this material, and it is the comparison the README's own scope implies. The practical difference is the database: Jellystat requires Postgres as a separate container.
How do I set up Jellystat?
Start the compose stack, open the app on port 3000, and complete the setup step that creates your login credentials. The README's environment table marks POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_IP, POSTGRES_PORT, JWT_SECRET and TZ as required.
Official sources
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.
[](https://hysenlabs.com/projects/cyfershepard-jellystat)