Skip to content

Ryot stores hundreds of remote images per media item, causing severe UI lag and no localized poster preference #1808

Description

@paShaman

Summary

During a bulk import (e.g. from Trakt), Ryot fetches all images for every media item from TMDB and stores them as remote URLs in metadata.assets.remote_images. On a library of ~900 items this results in ~200,000 stored image URLs — an average of ~200-700 per title (posters, backdrops, logos, profiles).

Opening any media details page makes the frontend load hundreds of images from TMDB at once, and quickly switching between titles causes severe UI lag / freezing (especially on mobile connections).

Observed behavior

  • metadataDetails returns 200-700 remoteImages URLs per item (e.g. The Batman 2026: 708, Disclosure Day: 412, Cape Fear: 329).
  • GraphQL response itself is fast (~15-500 ms), but the browser then downloads hundreds of images per page view.
  • On mobile data, a poster is first shown in English, then swapped to a localized (Russian) one — because the language of each image is not stored.

Root cause (from code)

In crates/providers/tmdb/src/base.rs, save_all_images() fetches GET /{media_type}/{id}/images and pushes every poster, backdrop, logo and profile URL into the assets:

if let Some(imgs) = new_images.posters { for image in imgs { images.push(self.get_image_url(image.file_path)); } }
if let Some(imgs) = new_images.backdrops { for image in imgs { images.push(self.get_image_url(image.file_path)); } }
if let Some(imgs) = new_images.logos { for image in imgs { images.push(self.get_image_url(image.file_path)); } }
if let Some(imgs) = new_images.profiles { for image in imgs { images.push(self.get_image_url(image.file_path)); } }

Additionally, in crates/providers/tmdb/src/models.rs, TmdbImage only keeps file_path — the iso_639_1 language field returned by TMDB is discarded, so Ryot has no way to prefer a localized poster.

Feature request

  1. Limit stored images per media item (configurable, e.g. max_images_per_media: 5) — keep the primary poster + backdrop, drop the rest.
  2. Preserve image language (iso_639_1) and let users prefer posters matching their languages preference (so Russian users get Russian posters immediately, without a flash of the English one).
  3. Optional: store images locally — allow downloading posters/backdrops to local storage (e.g. via the existing S3/file-storage integration) instead of hot-linking remote URLs. Benefits:
    • No dependency on TMDB's CDN availability (images still show if TMDB is slow or down).
    • Much faster loading for self-hosted instances, especially on LAN (no repeated downloads from the internet per page view).
    • Reduced external bandwidth usage.
    • Consistent behavior for users on slow/metered mobile connections.
  4. Optionally: skip re-fetching images during background metadata updates if images already exist (avoid re-hydrating hundreds of URLs on every nightly update for monitored items).

Impact

  • UI responsiveness on libraries of a few hundred items.
  • Mobile data usage (each page view currently triggers hundreds of image downloads).
  • Poster language consistency for non-English users.
  • Self-hosted instances would benefit from offline/instant image loading.

Thanks for the great project!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions