# ----------------------------------------------------------------------------- # AIOMetadata Addon - Environment Variables # For the full documentation of env variables visit: # https://github.com/cedya77/aiometadata/blob/dev/docs/ENVIRONMENT_VARIABLES.md # ----------------------------------------------------------------------------- # -- Core Configuration -- # The port the addon server will run on. PORT=3232 # The public hostname (e.g., https://your-domain.com or http://127.0.0.1:3232) where the addon is accessible. # This is crucial for Stremio to correctly locate your addon's manifest and resources. HOST_NAME=https://your-domain.com # The Node environment. Usually 'development' or 'production'. NODE_ENV=development # Set the logging level. Options: 'silent', 'fatal', 'error', 'warn', 'info', 'success', 'debug', 'trace', 'verbose'. # (Default: 'info' for production, 'debug' for development) LOG_LEVEL=info # Maximum number of log entries kept in the in-memory ring buffer for the dashboard logs tab. (Default: 10000) # LOG_BUFFER_SIZE=10000 # Compress HTTP responses with gzip or brotli, whichever the client negotiates. (Default: true) # A 20-item catalog page drops from about 99 KB to about 22 KB for roughly 1 ms of CPU. # Images, server-sent events and responses under 1 KB are skipped. # Set false only if a proxy in front is already compressing. # RESPONSE_COMPRESSION_ENABLED=true # Rebuild a catalog in the background when a request arrives near the end of its # cache lifetime, so the cached copy is served immediately and the rebuild never # lands on a user request. (Default: true) # Cache TTLs are unchanged, so nothing is served staler than CATALOG_TTL allows. # CATALOG_REFRESH_AHEAD_ENABLED=true # How much of an entry's lifetime counts as due for a background rebuild. (Default: 0.1) # 0.1 is the final tenth: the last 2.4 hours of a 24 hour catalog. # CATALOG_REFRESH_AHEAD_FRACTION=0.1 # How many background catalog rebuilds may run at once. (Default: 3) # Requests over the limit are skipped, not queued - the entry is still fresh. # CATALOG_REFRESH_AHEAD_MAX_CONCURRENT=3 # -- Database & Caching -- # Connection URI for the database. SQLite is used for local storage, but PostgreSQL is also supported. # For SQLite (default): DATABASE_URI=sqlite://addon/data/db.sqlite # For PostgreSQL: # DATABASE_URI=postgresql://user:password@localhost:5432/aiometadata # -- Geo-redundancy / read replica (PostgreSQL only, optional) -- # For multi-region deploys: point DATABASE_URI at the single writable PRIMARY # (shared by every region) and DATABASE_READ_URI at the LOCAL read replica in # this region. All writes (config saves, OAuth tokens, login rehash) go to the # primary; reads are served locally. Leave unset to use DATABASE_URI for both. # Falls back to the primary automatically if the replica is unreachable. # DATABASE_READ_URI=postgresql://user:password@local-replica:5432/aiometadata # # Set to false on replica-region instances to skip schema creation (DDL) on # startup. Run migrations once against the primary; replicas then boot without # attempting DDL. (Default: true) # RUN_MIGRATIONS=true # Connection string for your Redis instance, used for caching. REDIS_URL=redis://aiometadata_redis:6379 # -- Security & Admin -- # An optional key to protect administrative dashboard endpoints. # ADMIN_KEY=your-secure-random-key-here # HMAC secret signing the /poster, /logo and /background proxy URLs. # Falls back to ADMIN_KEY; unsigned if neither is set. # IMAGE_PROXY_SIGNING_SECRET=your-secure-random-key-here # Password for protected endpoints (if enabled in your deployment) # ADDON_PASSWORD=your-addon-password # -- Metrics Configuration -- # Set to "true" to disable all telemetry/metrics collection for the dashboard. # DISABLE_METRICS=false # Preferred language code for popular-content titles shown on the dashboard Content tab. # A title captured in this language is not overwritten by requests in other languages. # Leave blank to always use the most recent request's language. (Default: en) # DASHBOARD_METADATA_LANGUAGE=en # -- API Keys: server-side (start here) -- # These cover any user who has not supplied their own key, and they never leave # the server: /api/config publishes only the fact that they are set. This is the # way to fund an instance other people use. Every request from every user is # billed to them, so mind the provider's rate limits. BUILT_IN_TMDB_API_KEY= BUILT_IN_TVDB_API_KEY= BUILT_IN_FANART_API_KEY= BUILT_IN_RPDB_API_KEY= # # These two exist for the same reason but cost money per call, and every user of # the instance spends them. MDBList bills past 1000 calls a day and Gemini bills # per query, so set them on a private instance only. On a public one leave them # blank: users who want MDBList catalogs or AI search bring their own key. BUILT_IN_MDBLIST_API_KEY= BUILT_IN_GEMINI_API_KEY= # -- API Keys: published to the browser -- # # WARNING: TMDB_API_KEY, TVDB_API_KEY, FANART_API_KEY, RPDB_API_KEY, # MDBLIST_API_KEY and GEMINI_API_KEY are served to every visitor by /api/config, # in full, so the configure page can prefill them. That path stays open even with # AUTH_REQUIRE_SIGNIN=true, so requiring a login does not protect them. Set them # only where you would hand your keys to every user. On a shared instance leave # them blank, use the BUILT_IN_ keys above, and let users bring their own. # # TRAKT_CLIENT_ID and SIMKL_CLIENT_ID are in that payload too, which is expected: # an OAuth client id is public by design. Their secrets are not published, and # those are the ones that matter. A copied client id only lets someone else's # traffic count against your app's rate limit. # # Your TMDB API key. Essential for movie and some series metadata. # Legacy: TMDB_API is also supported for backwards compatibility. TMDB_API_KEY= # Your TVDB API key. Optional but highly recommended for series and some anime metadata. TVDB_API_KEY= # Your Fanart.tv API key. Optional, used for fetching high-quality logos and backgrounds. FANART_API_KEY= # Fanart.tv project API key. When set, user keys are sent as clientKey for faster image access. FANART_API_PROJECT_KEY= # Your Rating Poster DB (RPDB) API key. Optional, for displaying ratings on posters. RPDB_API_KEY= # Your MDBList API key. Optional, for integrating MDBList catalogs. MDBLIST_API_KEY= # Your Gemini API key. Optional, for AI features. GEMINI_API_KEY= # Your SimKL client ID SIMKL_CLIENT_ID= # Your SimKL client secret SIMKL_CLIENT_SECRET= # The redirect URI for SimKL OAuth (must match your SimKL app settings) # Example: https://your-domain.com/api/auth/simkl/callback SIMKL_REDIRECT_URI= # Time-to-live (in seconds) for caching SimKL activity checks. Reduces API spam when paginating, # and caps how long Up Next and Hide Simkl Watched lag behind what you just watched. # Simkl asks callers not to check more often than every 15 minutes. # Default: 1800 (30 minutes) SIMKL_ACTIVITIES_TTL=1800 # Jikan (MyAnimeList) API base URL — source for anime metadata. # Defaults to the public instance. NOTE: the public Jikan API shuts down Oct 1, 2026; # self-host your own instance (see README) and point this at it, e.g. # http://jikan_rest:8080/v4 when running both on the same Docker network. JIKAN_API_BASE=https://api.jikan.moe/v4 # Items per page for all MAL/Jikan catalogs. (Default: 25) # The public Jikan API caps this at 25. Only raise it on a self-hosted instance, # and keep it <= the instance's MAX_RESULTS_PER_PAGE or requests will 400. # MAL_PAGE_SIZE=25 # AniList API credentials (required for AniList integration) # Get these from https://anilist.co/settings/developer # Your AniList client ID ANILIST_CLIENT_ID= # Your AniList client secret ANILIST_CLIENT_SECRET= # The redirect URI for AniList OAuth (must match your AniList app settings) # Example: https://your-domain.com/anilist/callback ANILIST_REDIRECT_URI= # MyAnimeList API credentials (required for MAL watch tracking) # Get these from https://myanimelist.net/apiconfig # Your MAL client ID MAL_CLIENT_ID= # Your MAL client secret MAL_CLIENT_SECRET= # The redirect URI for MAL OAuth (must match your MAL app settings) # Example: https://your-domain.com/mal/callback MAL_REDIRECT_URI= # Trakt API credentials (required for Trakt integration) # Get these from https://trakt.tv/oauth/applications # Your Trakt client ID TRAKT_CLIENT_ID= # Your Trakt client secret TRAKT_CLIENT_SECRET= # The redirect URI for Trakt OAuth (must match your Trakt app settings) # Example: https://your-domain.com/api/auth/trakt/callback TRAKT_REDIRECT_URI= ## Disable trakt as a search option (recommended on public instances) DISABLE_TRAKT_SEARCH=false ## Max number of trakt parallel requests (recommend 10-15 for selfhosters) TRAKT_CONCURRENCY=5 ## Max concurrent getMeta() calls per catalog request (default: unlimited) ## Set to 20-30 on public instances to limit memory spikes from concurrent users. # META_CONCURRENCY= ## Log heap and in-memory cache stats to console at this interval (in minutes). 0 or unset disables. # HEAP_LOG_INTERVAL_MIN=30 ## Milliseconds to wait for an upstream poster/art image before serving the fallback. (Default: 10000) ## Raise this if a slow rating/poster-generation service times out on first render. # POSTER_PROXY_TIMEOUT_MS=10000 # -- TMDB Image Renditions -- ## Request smaller images from TMDB to save space. The three below are OFF by default.. ## Logos are the safest win, as they can be huge from the source but are rendered ## small by the client. # PREFER_SMALLER_LOGOS_TMDB=false ## Requesting smaller backgrounds is usually not recommended especially if they're being rendered ## on high resolution (4k) screens, enable this if saving space/bandwidth is more important than sharpness # PREFER_SMALLER_BACKDROPS_TMDB=false ## Landscape images are safer, as they are usually rendered in smaller boxes # PREFER_SMALLER_LANDSCAPE_TMDB=false ## Posters are the exception: they have always been requested at w600_and_h900_bestv2, ## so this one is ON by default and setting it to false is what changes artwork. ## It is also the most expensive to flip - a catalog page pulls one poster per tile. # PREFER_SMALLER_POSTERS_TMDB=true ## None of these affect meta already in the cache until META_TTL expires. ## Superseded images stay on disk unreferenced and are reclaimed as they age out. # -- Built-in Image Cache -- ## Cache artwork on disk and serve it from /poster-cache on this addon's own port. ## No extra container, port, or volume: images are stored under addon/data/poster-cache, ## inside the data volume you already mount. Multi-replica/k8s deploys get an ## independent cache per replica; run a shared external proxy instead if that matters. # ENABLE_BUILTIN_POSTER_CACHE=false ## Posters are cached by default. Everything below is opt-in, so turning the cache ## on never changes disk usage unexpectedly. All are also toggles in the dashboard. ## Backgrounds are the largest images served — the biggest bandwidth win. # POSTER_CACHE_BACKGROUNDS=false # POSTER_CACHE_LANDSCAPE_POSTERS=false # POSTER_CACHE_LOGOS=false ## Episode thumbnails are by far the most numerous: one long-running series can add ## hundreds of images. Expect disk usage to grow quickly. # POSTER_CACHE_THUMBNAILS=false ## Cache the images the addon renders itself: rating-overlaid posters (when Proxy ## Rating & Custom Art is on) plus the blur/resize/banner-to-background transforms. ## ON by default with the cache; set false only to keep these out of it. Custom art ## URLs pass through unchanged, so they follow their own type's toggle above. # POSTER_CACHE_PROCESSED_IMAGES=true ## Whether a signed art URL may reach a private/LAN address. Fine when you are the ## only one configuring art patterns. Set false on a public multi-user instance: ## patterns are user-supplied, so a user could aim one inside your network. ## (Default: true) # POSTER_PROXY_ALLOW_PRIVATE=true ## Comma-separated hosts allowed even when they resolve to a private/LAN address. ## Needed if your rating/art provider (e.g. a self-hosted PosterPlus) runs on your ## own network; without it those fetches are blocked as SSRF. Everything else stays blocked. # POSTER_CACHE_ALLOWED_HOSTS=postersplus,xrdb ## DISK budget. Least-recently-used images are evicted once exceeded. (Default: 10g) # POSTER_CACHE_MAX_SIZE=10g ## RAM budget for the hottest images, layered in front of the disk cache. A memory ## hit skips the disk read AND its per-request allocation, lowering GC pressure. ## This is on top of the addon's own footprint. Set to 0 for disk only. ## (Default: 128m) # POSTER_CACHE_MEMORY_SIZE=128m ## How long a cached image stays fresh. Fractional allowed (0.5 = 12h); 0 never ## expires. Expiry is not a re-download: sources that send an ETag or ## Last-Modified are asked to confirm the stored copy, and a 304 restarts validity ## with no body transferred. ## If you use a rating poster service or a custom art URL pattern, give its domain ## a shorter rule below — those URLs name a slot rather than a file, so the bytes ## change while the URL does not, and a stale rating sits there until it expires. ## (Default: 30) # POSTER_CACHE_TTL_DAYS=30 ## Derive each image's validity from the headers its own source sent, instead of ## the flat value above; where a source promises nothing we can act on, the flat ## value still applies. Expect a year for TMDB, days for MAL and metahub, hours or ## less for rating services. A source asking not to be cached at all is then ## honoured too, and its image is served without being stored. Not a substitute ## for a rule on RPDB: it advertises weeks and cannot be revalidated cheaply. ## (Default: false) # POSTER_CACHE_INFER_TTL=false ## Per-provider overrides, as a JSON list. Each rule names a domain and one of ## "default" (the flat validity above), "infer" (follow that provider's own ## headers), "custom" (a fixed "ttl" such as 6h, 30d, 1y) or "bypass" (serve ## without ever storing). A rule beats the toggle above, which beats the flat ## validity. A domain covers its subdomains, and the more specific rule wins, and ## one rule covers every image class for that host. Switching a provider to ## "bypass" leaves what it already cached on disk — POST ## /api/dashboard/poster-cache/purge {"domain":"…"} to reclaim it. ## The rating services worth a rule: api.ratingposterdb.com, api.top-posters.com, ## btttr.cc, extendedratings.com, postersplus.elfhosted.com. ## (Default: unset — no rules, every provider on the flat validity) # POSTER_CACHE_PROVIDER_POLICIES=[{"domain":"api.ratingposterdb.com","policy":"custom","ttl":"6h"}] ## How long players/browsers may keep an image from the /poster, /logo and ## /background proxy routes. Short by default: those routes revalidate on request ## parameters, not bytes, so only expiry picks up changed art. Fractional allowed ## (0.25 = 6h), 0 never expires, capped by the served image's own remaining ## validity. (Default: 1) # POSTER_PROXY_MAX_AGE_DAYS=1 ## Drop images not requested for this many days. (Default: 30) # POSTER_CACHE_INACTIVE_DAYS=30 ## Images larger than this are passed through to the client uncached, so one ## oversized asset cannot consume the whole budget. (Default: 20m) # POSTER_CACHE_MAX_OBJECT_BYTES=20m ## Override where cached images live. (Default: addon/data/poster-cache) # POSTER_CACHE_DIR= ## Ceiling on simultaneous downloads of uncached images. Each in-flight fetch holds ## an image in memory, so this bounds peak memory during a burst of cache misses. ## Duplicate requests for the same image are coalesced and don't use a slot. (Default: 128) # POSTER_CACHE_FETCH_CONCURRENCY=128 ## Cached images above this are streamed from disk instead of buffered, so bursts of ## large artwork can't pile up on the heap. (Default: 256k) # POSTER_CACHE_STREAM_THRESHOLD=256k ## Log every image request. Off by default: at scale it floods the log buffer and ## evicts everything else. A one-line summary is logged each minute regardless. # POSTER_CACHE_LOG_REQUESTS=false ## Upgrading from the OLD bundled nginx poster cache? Nothing to configure: the ## old cache is detected at /var/cache/nginx/posters and imported once, so long as ## you leave that volume mounted for one start. A marker stops it running twice. ## Set a path only if your old cache lived somewhere non-standard, or 'off' to skip. # POSTER_CACHE_IMPORT_NGINX_DIR=off ## Public URL clients fetch images through. Leave empty with the built-in cache — ## it derives {HOST_NAME}/poster-cache automatically. Set it only when pointing at ## an external caching proxy. # POSTER_PROXY_PREFIX_URL=https://poster-cache.example.com ## Internal URL used for server-side image warming (defaults to the built-in cache ## on 127.0.0.1 when enabled; otherwise falls back to POSTER_PROXY_PREFIX_URL). # POSTER_WARMUP_URL=http://poster-cache:8888 ## Spacing between requests (recommend 100ms for selfhosters) TRAKT_MIN_TIME=200 # -- Cache TTL Configuration -- # Catalog cache time-to-live in seconds (default: 86400 = 24 hours) CATALOG_TTL=86400 # Meta cache time-to-live in seconds (default: 604800 = 7 days) META_TTL=604800 # -- Timezone Configuration -- # Set the timezone for the server (e.g., America/New_York) # TZ=America/New_York # -- Cache Performance & Warming -- # Set to "false" to disable automatic cache warming on startup. (Default: true) ENABLE_CACHE_WARMING=true # Specify a custom UUID to use for the cache warming config. Highly recommended for private instances. CACHE_WARMUP_UUIDS= CACHE_WARMUP_UUID=system-cache-warmer # Choose warm-up mode, 'essential' warms select TMDB/MAL catalogs with limited depth # whilst 'comprehensive' warms all the catalogs present in a UUID, at the max depth specified below # NOTE: comprehensive *requires* a CACHE_WARMUP_UUID to be set CACHE_WARMUP_MODE=essential # How often (in hours) to warm popular TMDB content. (Default: 24, Minimum: 12) CATALOG_WARMUP_INTERVAL_HOURS=24 # Initial delay before starting catalog warming (in seconds) CATALOG_WARMUP_INITIAL_DELAY_SECONDS=300 # Set the max page number to warm per catalog (Default: 100) CATALOG_WARMUP_MAX_PAGES_PER_CATALOG=100 # Resume warming on restart (Default: true) CATALOG_WARMUP_RESUME_ON_RESTART=true # Enable quiet hours for catalog warming (Default: false) CATALOG_WARMUP_QUIET_HOURS_ENABLED=false # Quiet hours time range (e.g., 02:00-06:00) # Catalog warming will never run during the configured quiet hours CATALOG_WARMUP_QUIET_HOURS=02:00-06:00 # Delay between catalog warmup tasks (in ms) CATALOG_WARMUP_TASK_DELAY_MS=100 # Logging level for catalog warming CATALOG_WARMUP_LOG_LEVEL=info # Auto warmup when CACHE_EPOCH is bumped, which supersedes every cached key. # (Formerly CATALOG_WARMUP_AUTO_ON_VERSION_CHANGE, still accepted.) CATALOG_WARMUP_AUTO_ON_EPOCH_CHANGE=false # Set to "false" to disable warming of popular TMDB content. (Default: true) TMDB_POPULAR_WARMING_ENABLED=true # How often (in hours) to warm cache (Default: 24) CACHE_WARM_INTERVAL_HOURS=24 # Language to use for cache warming (Default: en-US) CACHE_WARM_LANGUAGE=en-US # Enable cache warmup on startup (Default: true) CACHE_WARMUP_ON_STARTUP=true # -- MAL Catalog Background Warming -- # Set to "false" to disable MAL-specific catalog warming. (Default: true) MAL_WARMUP_ENABLED=true # Interval in hours for MAL catalog warming. (Default: 6) MAL_WARMUP_INTERVAL_HOURS=6 # Initial delay before starting MAL warming (in seconds) MAL_WARMUP_INITIAL_DELAY_SECONDS=30 # Delay between MAL warmup tasks (in ms) MAL_WARMUP_TASK_DELAY_MS=100 # Enable quiet hours for MAL warming (Default: false) MAL_WARMUP_QUIET_HOURS_ENABLED=false # Quiet hours range for MAL warming (e.g., 2-8) # MAL-specific catalog warming will never run during the configured quiet hours MAL_WARMUP_QUIET_HOURS_RANGE=2-8 # Number of priority pages for MAL warming MAL_WARMUP_PRIORITY_PAGES=2 # Enable/disable metadata warming for MAL MAL_WARMUP_METADATA=false # Enable priority warming for MAL MAL_WARMUP_PRIORITY=true # Enable scheduled MAL warming MAL_WARMUP_SCHEDULE=true # Enable decade-based MAL warming MAL_WARMUP_DECADES=false # Enable SFW mode for MAL warming MAL_WARMUP_SFW=true # Logging level for MAL warming MAL_WARMUP_LOG_LEVEL=normal # -- Cache Cleanup Scheduler -- # Enable automatic cache cleanup (Default: true) CACHE_CLEANUP_AUTO_ENABLED=true # Enable quiet hours for cache cleanup (Default: false) CACHE_CLEANUP_QUIET_HOURS_ENABLED=false # Quiet hours for cache cleanup (e.g., 02:00-06:00) # Cache cleanup will never run during the configured quiet hours CACHE_CLEANUP_QUIET_HOURS=02:00-06:00 # -- In-Memory Cache Limits -- # Max entries in the per-user Fanart.tv client cache. (Default: 2000) # Sized for popular public instances. Lower on memory-constrained self-hosts. FANART_CLIENT_CACHE_MAX=2000 # Max entries in the TMDB scraped-IMDb-ID cache. (Default: 10000) TMDB_SCRAPED_IMDB_CACHE_MAX=10000 # -- Catalog Configuration -- # The number of items to display per page in catalogs. (Default: 20) CATALOG_LIST_ITEMS_SIZE=20 # Optional cap on catalog count per user configuration. # When set to a positive integer, saving a configuration with more catalogs than this limit is rejected. # Leaving this unset preserves the unbounded behaviour. # MAX_CATALOGS=200 # -- UI & Customization -- # An optional suffix to add to the addon's name in the manifest (e.g., "| My Server"). # ADDON_NAME_SUFFIX= # Optional custom HTML blurb to display on the configuration page. # CUSTOM_DESCRIPTION_BLURB= # -- Advanced/Proxy Configuration -- # Optional SOCKS proxy for all requests (e.g., socks5://user:pass@host:port). # SOCKS_PROXY_URL= # Optional HTTP proxy for all requests. # HTTP_PROXY= # Optional HTTPS proxy for all requests. # HTTPS_PROXY= # Optional SOCKS proxy for TMDB requests (e.g., socks5://user:pass@host:port). # TMDB_SOCKS_PROXY_URL= # Optional SOCKS proxy for Jikan/MAL requests. # MAL_SOCKS_PROXY_URL= # Optional SOCKS proxy for MDBList requests. # Optional: Override the logo URL in the manifest # ADDON_LOGO_URL=https://yourdomain.com/yourlogo.png # -- MovieLens Integration -- # Personalized recommendation catalogs backed by a user's MovieLens account. # REQUIRED to enable the integration: AES key encrypting stored MovieLens passwords. # This is env-only and never editable from the dashboard. Rotating it orphans all # stored credentials, forcing every user to reconnect their MovieLens account. # MOVIELENS_CRED_KEY= # Enable the scheduled background job that re-syncs Trakt/Simkl/MDBList ratings # into connected MovieLens accounts. (Default: true) Requires a restart. ENABLE_MOVIELENS_SYNC=true # How often the scheduled job re-syncs ratings, in hours. (Default: 24) Requires a restart. MOVIELENS_SYNC_INTERVAL_HOURS=24 # Minimum seconds between user-triggered "Import ratings" runs. (Default: 21600) MOVIELENS_MANUAL_SYNC_COOLDOWN_SECONDS=21600 # Timeout for requests to the MovieLens API, in ms. (Default: 25000) MOVIELENS_REQUEST_TIMEOUT_MS=25000 # Left commented so a copied .env does not pin these past a newer default. # Base URL for the MovieLens API. (Default: https://movielens.org/api) # MOVIELENS_API_BASE=https://movielens.org/api # User-Agent sent to MovieLens. MovieLens sits behind Cloudflare and rejects # requests without a browser-like User-Agent. # MOVIELENS_USER_AGENT=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 # Referer header used for the MovieLens login request. (Default: https://movielens.org/login) # MOVIELENS_LOGIN_REFERER=https://movielens.org/login # Referer header used for the MovieLens CSV ratings-import request. # MOVIELENS_IMPORT_REFERER=https://movielens.org/profile/settings/import-export # Time-to-live for MovieLens catalog cache entries, in seconds. (Default: 3600) # Per-catalog cacheTTL set in the UI overrides this. MOVIELENS_CATALOG_TTL_SECONDS=3600 # Time-to-live for cached MovieLens account metadata, in seconds. (Default: 43200) # Covers the recommendation engine and taste tags. Lower this to react faster when # a user upgrades from the "bard" engine to a personalized one. # Replaces MOVIELENS_GROUPTAGS_TTL_SECONDS, which is still honoured as a fallback. MOVIELENS_USERMETA_TTL_SECONDS=43200 # Safety cap on pages fetched when paginating a MovieLens user list. (Default: 50) MOVIELENS_LIST_MAX_PAGES=50 # -- Metahub Artwork Checks -- # Time-to-live for cached metahub logo/image existence checks, in seconds. (Default: 86400) METAHUB_IMAGE_EXISTS_TTL_SECONDS=86400 # Timeout for the metahub image existence HEAD request, in ms. (Default: 4000) METAHUB_IMAGE_HEAD_TIMEOUT_MS=4000 # Cache epoch — bumped by hand when a cached payload's shape changes, so ordinary # releases no longer discard good cache. Governs both tiers: Redis keys are # prefixed with it, and cold-store rows record it. Raise it to force a rebuild # without waiting for a release. # CACHE_EPOCH=1 # --- Meta Cold Store (disk L2 for stable metadata; off by default) --- # Persists only provably-stable metadata (old films, ended series, finished anime) # in a dedicated SQLite file, so Redis eviction stops forcing upstream re-fetches. # META_COLD_STORE_ENABLED=false # META_COLD_STORE_PATH=addon/data/metacache.sqlite # META_COLD_STORE_MAX_BYTES=2gb # lz4-compress stored payloads (~50% smaller disk footprint). Safe to toggle at # any time — existing entries stay readable either way. # META_COLD_STORE_COMPRESSION=true # COLD_TTL_FROZEN=180d # COLD_TTL_STABLE=60d # SETTLE_MOVIE=180d # SETTLE_SERIES=90d # FROZEN_AGE=2y # COLD_STORE_INACTIVE_DAYS=30 # How long the dashboard reuses cold-store size figures before recounting. Each # recount is a synchronous scan that blocks the event loop; 0 recounts always. # COLD_STORE_STATS_TTL=30s # Image warming runs through one bounded queue shared by every catalog, instead of # an unbounded chain per catalog. Concurrency adapts to event-loop lag, so it uses # whatever headroom catalog warming leaves and backs off when it does not. # IMAGE_WARM_QUEUE=true # IMAGE_WARM_QUEUE_MAX=50000 # IMAGE_WARM_CONCURRENCY_MIN=4 # IMAGE_WARM_CONCURRENCY_MAX=48 # IMAGE_WARM_TARGET_LAG_MS=20