Ryot: Self-Hosted Media Tracking for Movies, Books, Games, and More
Tracking what you watch, read, play, and listen to across multiple platforms is a fragmented experience. Your movie history lives in Letterboxd, your reading list in Goodreads, your game backlog in a spreadsheet, and your podcast queue in whatever app you're using this month. Each platform has its own login, its own data format, and its own terms of service governing your data.
Photo by Rob Wingate on Unsplash
Ryot (Roll Your Own Tracker) is a self-hosted media tracker that consolidates all of this into a single application. Track movies, TV shows, anime, manga, books, audiobooks, podcasts, video games, visual novels, and even workouts -- all in one place, on your own server. Your data stays yours, and you're not locked into any platform's ecosystem.

What Ryot Tracks
Unlike specialized tools that focus on one media type, Ryot is a unified tracker across multiple categories:
- Movies -- metadata from TMDB, track watched status, ratings, reviews
- TV Shows -- per-season and per-episode tracking, progress tracking
- Anime -- metadata from Anilist, season/episode tracking
- Manga -- chapter-level tracking with Anilist metadata
- Books -- metadata from OpenLibrary and Google Books, page progress tracking
- Audiobooks -- Audible metadata integration, listening progress
- Podcasts -- episode-level tracking via iTunes/podcast index
- Video Games -- metadata from IGDB, platform-specific tracking (PC, console, handheld)
- Visual Novels -- tracking via VNDB metadata
- Workouts -- exercise logging with sets, reps, weight, duration
- Custom media -- track anything that doesn't fit the built-in categories
Each media type pulls metadata from its respective source automatically. When you add a movie, Ryot fetches the poster, synopsis, cast, runtime, and release date from TMDB. When you add a book, it pulls the cover, author, page count, and description from OpenLibrary.
Why Self-Host Your Media Tracking
Commercial tracking services have a few problems that self-hosting solves:
Data ownership
Letterboxd, Goodreads, and MyAnimeList all hold your tracking data hostage. If the service shuts down, changes its API, or decides to monetize your data differently, you lose years of carefully maintained lists. With Ryot, your data lives in a PostgreSQL database on your server that you can back up, export, and query however you want.
Privacy
Commercial trackers build profiles of your media consumption habits. What you watch, when you watch it, how quickly you binge a series -- this is valuable behavioral data. Ryot runs locally and doesn't phone home.
Consolidation
Instead of maintaining accounts on five different platforms, you have one interface for everything. Your "currently consuming" list spans movies, books, games, and podcasts in a single view.
Customization
Rate media on whatever scale you want. Add custom metadata fields. Create collections that span media types (e.g., "Cyberpunk" containing movies, books, games, and anime). No platform tells you how to organize your data.
Ryot vs. Other Tracking Tools
Ryot occupies a unique niche -- it's a multi-media tracker rather than a single-purpose tool.
| Feature | Ryot | Tautulli | Overseerr | Bookwyrm | Stump |
|---|---|---|---|---|---|
| Movies/TV | Yes | Plex stats only | Request mgmt | No | No |
| Books | Yes | No | No | Yes (social) | No |
| Video games | Yes | No | No | No | No |
| Podcasts | Yes | No | No | No | No |
| Anime/manga | Yes | No | No | No | No |
| Workouts | Yes | No | No | No | No |
| Comics/manga reader | No | No | No | No | Yes |
| Plex integration | Yes (import) | Native | Native | No | No |
| Social features | Limited | No | No | Fediverse | No |
| Self-hosted | Yes | Yes | Yes | Yes | Yes |
| Multi-user | Yes | Yes | Yes | Yes | Yes |
| API | GraphQL | REST | REST | ActivityPub | REST |
When to pick Ryot
- You want one tool to track movies, books, games, podcasts, and more
- You care about data ownership and want everything in your own database
- You want to import existing data from Letterboxd, Goodreads, IMDB, and other services
- You don't need a media server integration (Ryot is a tracker, not a player)
When to pick alternatives
- Tautulli -- if you specifically want Plex viewing statistics and monitoring. Tautulli is deeply integrated with Plex and provides detailed playback analytics. It doesn't track media you consume outside Plex.
- Overseerr -- if you want a media request system for your Plex/Jellyfin server. Overseerr is about requesting and managing media acquisition, not personal tracking.
- Bookwyrm -- if you want a social reading platform with Fediverse integration. Bookwyrm is specifically for books and emphasizes the social/review aspect over personal tracking.
- Stump -- if you want a comic/manga reader and library manager. Stump serves files and tracks reading progress for comics, not general media tracking.
Ryot doesn't replace any of these tools -- it complements them. You might use Tautulli for Plex analytics, Overseerr for media requests, and Ryot for personal tracking across all media types.
Like what you're reading? Subscribe to Self-Hosted Weekly — free weekly guides in your inbox.
Self-Hosting Ryot: Docker Compose Setup
Ryot requires PostgreSQL as its database backend. Here's a complete Docker Compose configuration:
# docker-compose.yml
services:
ryot:
image: ghcr.io/ignisda/ryot:latest
container_name: ryot
ports:
- "8000:8000"
environment:
# Database connection
DATABASE_URL: postgres://ryot:your-secure-password@ryot-db:5432/ryot
# Server configuration
SERVER_INSECURE_COOKIE: "false"
# Set to "true" if not using HTTPS (development only)
# TMDB API key for movie/TV metadata
MOVIES_TMDB_ACCESS_TOKEN: "your-tmdb-read-access-token"
# IGDB credentials for video game metadata
VIDEO_GAMES_TWITCH_CLIENT_ID: "your-twitch-client-id"
VIDEO_GAMES_TWITCH_CLIENT_SECRET: "your-twitch-client-secret"
# Audible locale for audiobook metadata
AUDIO_BOOKS_AUDIBLE_LOCALE: "us"
# Optional: configure timezone
TZ: "America/New_York"
volumes:
- ryot-data:/data
depends_on:
ryot-db:
condition: service_healthy
restart: unless-stopped
ryot-db:
image: postgres:16-alpine
container_name: ryot-db
environment:
POSTGRES_USER: ryot
POSTGRES_PASSWORD: your-secure-password
POSTGRES_DB: ryot
volumes:
- ryot-postgres:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ryot"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
volumes:
ryot-data:
ryot-postgres:
Getting API keys
Ryot uses external APIs for metadata. Here's how to get the keys:
TMDB (movies and TV shows):
- Create an account at themoviedb.org
- Go to Settings > API > Create > Developer
- Copy the "Read Access Token" (not the API Key)
IGDB/Twitch (video games):
- Create a Twitch developer account at dev.twitch.tv
- Register a new application
- Copy the Client ID and generate a Client Secret
Other metadata sources (OpenLibrary, Anilist, iTunes podcast index) don't require API keys -- Ryot uses their public APIs.
Starting Ryot
docker compose up -d
Access the web interface at http://your-server:8000. The default credentials are:
- Username: admin
- Password: admin
Change these immediately after first login.
Reverse proxy configuration
For production use, put Ryot behind a reverse proxy with HTTPS. Here's a Caddy example:
ryot.yourdomain.com {
reverse_proxy ryot:8000
}
Or with Nginx:
server {
listen 443 ssl;
server_name ryot.yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Importing Existing Data
One of Ryot's strongest features is its import system. You don't have to start from scratch -- bring your tracking history from other platforms.
Supported import sources
| Source | Media types | Import format |
|---|---|---|
| Goodreads | Books | CSV export |
| Letterboxd | Movies | CSV export |
| IMDB | Movies, TV | CSV export |
| MyAnimeList | Anime, manga | XML export |
| Trakt | Movies, TV | API (OAuth) |
| Audiobookshelf | Audiobooks | API |
| MediaTracker | All types | JSON export |
| Movary | Movies | JSON export |
| StoryGraph | Books | CSV export |
| Plex | Movies, TV | Watchlist |
| Jellyfin | Movies, TV | API |
| Generic JSON | Any | Custom JSON |
Import process
- Navigate to Settings > Imports in the Ryot dashboard
- Select your source platform
- Upload the export file or provide API credentials
- Ryot matches items against its metadata sources and imports your ratings, reviews, and progress
For Trakt imports, you'll authenticate via OAuth and Ryot pulls your entire watch history. For Goodreads, export your library as CSV from Goodreads settings and upload it directly.
Handling import conflicts
When importing from multiple sources, duplicates are detected by matching against metadata IDs. If you've tracked the same movie in both Letterboxd and Trakt, Ryot merges the data -- keeping the most recent rating and combining watch dates.
Using Ryot Day-to-Day
Adding media
The search function works across all media types simultaneously. Type "Dune" and you'll see the movie, the book, the video game, and the TV series all in one result set. Select the one you want and mark it as:
- In Progress -- currently watching/reading/playing
- Completed -- finished
- On Hold -- paused, will return to it
- Dropped -- started but won't finish
- Planned -- want to consume eventually
Rating and reviewing
Ryot supports customizable rating scales:
- Star rating (1-5 or 1-10)
- Percentage (0-100)
- Binary (thumbs up/down)
You can write text reviews, which are stored locally and can optionally be shared if you enable social features.
Collections
Create custom collections that span media types. Examples:
- "2026 Challenge" -- everything you want to consume this year
- "Cyberpunk" -- cyberpunk movies, books, games, and anime
- "Comfort Rewatches" -- shows and movies you return to
- "Book Club" -- the current book club selection plus history
Progress tracking
For long-form media, Ryot tracks granular progress:
- Books: current page out of total pages
- TV shows: which episodes you've watched per season
- Manga: chapter progress
- Audiobooks: listening progress (percentage or timestamp)
- Video games: completion percentage and hours played
Workout tracking
Ryot includes a workout tracker, which is an unusual feature for a media tracker. You can log:
- Exercises (bench press, squats, running, etc.)
- Sets, reps, weight, duration, distance
- Workout templates for recurring routines
- Progress over time with charts
This isn't as feature-rich as a dedicated fitness app, but it's convenient if you want all your tracking in one place.
GraphQL API
Ryot exposes a full GraphQL API, which opens up automation and integration possibilities.
Authentication
# Get an auth token
curl -X POST http://ryot:8000/backend/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "mutation { loginUser(input: { username: \"admin\", password: \"yourpassword\" }) { apiKey } }"
}'
Querying your media
# Get all media currently in progress
query {
mediaList(input: { lot: MOVIE, filter: { status: IN_PROGRESS } }) {
items {
title
publishYear
averageRating
}
}
}
Adding media via API
# Mark a movie as completed
mutation {
commitMedia(input: {
identifier: "693134"
lot: MOVIE
source: TMDB
}) {
id
}
}
Integration ideas
- Webhook on completion -- trigger a notification when you finish a book or movie
- Automated imports -- script periodic imports from Plex or Jellyfin
- Dashboard widgets -- pull "currently watching/reading" into your homepage dashboard
- Year-in-review -- query your data to generate annual consumption statistics
Multi-User Setup
Ryot supports multiple users with separate libraries, ratings, and progress. Each user has:
- Their own media library and tracking history
- Independent ratings and reviews
- Separate collections and lists
- Individual import history
This makes Ryot useful for households where multiple people want to track their media consumption independently.
User management
Create additional users from Settings > Users. Each user gets their own login and isolated data. There's no shared library concept -- if two users both track the same movie, they each have independent entries.
Sharing and social
Ryot has basic social features: users can follow each other and see what others are tracking (if privacy settings allow). This is optional and disabled by default.
Backup and Data Export
Database backup
Since all data lives in PostgreSQL, standard database backup practices apply:
# Dump the database
docker exec ryot-db pg_dump -U ryot ryot > ryot-backup.sql
# Automated daily backup with cron
0 3 * * * docker exec ryot-db pg_dump -U ryot ryot | gzip > /backups/ryot-$(date +\%Y\%m\%d).sql.gz
Data export
Ryot supports exporting your data in JSON format from the web interface. Navigate to Settings > Exports and download a full export. This includes all your media entries, ratings, reviews, progress, collections, and workout data.
The export format is documented, so you can write scripts to process or migrate your data if needed.
Performance and Resource Usage
Ryot is reasonably lightweight:
- RAM: ~150-200 MB for the Ryot container, plus PostgreSQL overhead
- CPU: Minimal except during imports (metadata fetching is API-bound)
- Storage: Database size depends on library size. A library of 1,000 items typically uses under 100 MB including cached metadata
- Startup time: Fast (under 10 seconds)
For large libraries (10,000+ items), the initial metadata fetch can take time, but day-to-day performance remains snappy.
Honest Trade-offs
Ryot is excellent if you:
- Track media across multiple categories and want one unified interface
- Value data ownership and want everything in your own database
- Have existing data in Letterboxd, Goodreads, Trakt, or MAL that you want to consolidate
- Want a GraphQL API for automation and custom integrations
- Run a household with multiple users who each track their own media
Ryot has limitations:
- It's a tracker, not a media server. It doesn't play, stream, or serve media files.
- Social features are basic compared to platforms like Letterboxd or Bookwyrm.
- The workout tracker is functional but basic compared to dedicated fitness apps.
- Metadata quality depends on the upstream sources (TMDB, OpenLibrary, IGDB). Obscure titles may have incomplete data.
- No mobile app yet -- the web interface is responsive but a native app would be better for quick logging.
The bottom line: If you've ever wished you could see your movies, books, games, and podcasts in one tracking interface without relying on five different commercial platforms, Ryot is exactly what you're looking for. The import system makes migration painless, the GraphQL API enables automation, and the multi-category approach means you'll actually use one tracker instead of maintaining several.
