Skip to content

Scheduled Tasks

RomM runs background work through RQ (Redis Queue). Tasks fall into four categories:

  • Scheduled: cron-driven, run on their own
  • Watcher: triggered by filesystem events
  • Manual: user-triggered from the UI or API
  • Enqueued: side effects of user actions (a scan on the /scan page, a metadata refresh on a ROM edit, etc.)

The full table

Task Type Default schedule Enable var Schedule/delay var Purpose
Scheduled rescan Scheduled 0 3 * * * ENABLE_SCHEDULED_RESCAN SCHEDULED_RESCAN_CRON Rescans the entire library.
Scheduled LaunchBox metadata update Scheduled 0 4 * * * ENABLE_SCHEDULED_UPDATE_LAUNCHBOX_METADATA SCHEDULED_UPDATE_LAUNCHBOX_METADATA_CRON Updates the LaunchBox metadata store.
Scheduled Switch TitleDB update Scheduled 0 4 * * * ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON Updates the Nintendo Switch TitleDB file.
Build recommendations index Scheduled 30 5 * * * ENABLE_SCHEDULED_BUILD_RECOMMENDATIONS SCHEDULED_BUILD_RECOMMENDATIONS_CRON Rebuilds the similar-games index from library metadata, play history and collections.
Convert images to WebP Scheduled 0 4 * * * ENABLE_SCHEDULED_CONVERT_IMAGES_TO_WEBP SCHEDULED_CONVERT_IMAGES_TO_WEBP_CRON Convert existing image files (PNG, JPG, BMP, TIFF, GIF) to WebP format for better performance.
Scheduled ZIP cache cleanup Scheduled 0 4 * * * - - Removes stale cached ZIP files based on tiered TTL. Always on, not configurable.
Cleanup orphaned resources Scheduled 0 5 * * * ENABLE_SCHEDULED_CLEANUP_ORPHANED_RESOURCES SCHEDULED_CLEANUP_ORPHANED_RESOURCES_CRON Clean up orphaned resources in the ROMs directory.
Scheduled netplay cleanup Scheduled */30 * * * * - - Cleans up empty netplay rooms. Always on, not configurable.
Scheduled upload tmp cleanup Scheduled 0 * * * * - - Cleans up orphaned chunked-upload temp directories. Always on, not configurable.
Scheduled RetroAchievements progress sync Scheduled 0 4 * * * ENABLE_SCHEDULED_RETROACHIEVEMENTS_PROGRESS_SYNC SCHEDULED_RETROACHIEVEMENTS_PROGRESS_SYNC_CRON Updates RetroAchievements progress for all users.
Push-Pull Sync Scheduled */30 * * * * ENABLE_SYNC_PUSH_PULL SYNC_PUSH_PULL_CRON Sync saves with devices via SSH/SFTP.
Cleanup missing ROMs Manual - - - Delete all ROMs flagged as missing from the filesystem from the database.
Cleanup missing firmware Manual - - - Delete all firmware flagged as missing from the filesystem from the database.
Sync Folder Scan Manual - ENABLE_SYNC_FOLDER_WATCHER - Scan device sync folders for new save files.
Recompute save content hashes Manual - - - Re-scan every save row and rewrite content_hash with the current compute_content_hash algorithm. One-time recovery after the zip-hash dispatch fix.
Filesystem watcher Watcher - ENABLE_RESCAN_ON_FILESYSTEM_CHANGE RESCAN_ON_FILESYSTEM_CHANGE_DELAY Watch the library folder and trigger a rescan on changes.
Sync folder watcher Watcher - ENABLE_SYNC_FOLDER_WATCHER SYNC_FOLDER_SCAN_DELAY Watch the sync folder and trigger a scan on changes.

Configuring cadence

Every scheduled task takes a standard 5-field cron expression:

  • 0 3 * * *: 3 AM daily
  • 0 */6 * * *: every 6 hours, on the hour
  • */30 * * * *: every 30 minutes
  • 0 2 * * 0: 2 AM every Sunday

Set the env var and restart the container. The scheduler picks up the new schedule as soon as RomM is back.

Enabling a scheduled task

Most tasks have an ENABLE_* environment variable, like ENABLE_SCHEDULED_UPDATE_LAUNCHBOX_METADATA=true which enables the LaunchBox sync. Set both the enable var and its cron var, since a task with an empty cron string has nothing to schedule and stays unscheduled even when enabled.

Unlike other tasks, build recommendations index ships enabled, because the recommendation sections read that index and similar games sits empty without it. Setting ENABLE_SCHEDULED_BUILD_RECOMMENDATIONS=false stops the nightly rebuild, but doesn't hide either section; users turn those off in their own settings.

The housekeeping tasks (netplay cleanup, upload tmp cleanup, ZIP cache cleanup) are always on and have no env vars. Check the env var reference for the full list.

Triggering a task manually

From the Administration page

Administration → Tasks lists every task with its status and a way to run it. Anyone with the tasks.run scope can fire one off, scheduled tasks included, which saves waiting for the next cron tick after a config change.

From the API

POST /api/tasks/run/{task_name}
Authorization: Bearer <token-with-tasks.run>

Monitoring tasks

  • Live: Administration → Tasks page shows every task's current status (queued, running, idle, failed).
  • API: GET /api/tasks/status for a JSON summary. Wire this to an uptime monitor if you want alerts.
  • Logs: docker logs romm → look for rq.worker lines.

A task that's been "running" for hours is usually a scan that hit SCAN_TIMEOUT, and the logs will say so. Tasks that fail leave a stack trace in the container logs, and the RQ failed queue retains the last few for inspection.

Tuning for small hosts

On a Raspberry Pi or NAS with 2 GB of RAM and/or a single CPU core:

  • Raise the cron intervals (daily → weekly) for the nightlies
  • Set SCAN_WORKERS=1 and WEB_SERVER_CONCURRENCY=1, both of which default to 4
  • Enable the watcher but raise RESCAN_ON_FILESYSTEM_CHANGE_DELAY to 30+ minutes
  • Disable image conversion if you don't care about WebP (ENABLE_SCHEDULED_CONVERT_IMAGES_TO_WEBP=false)
  • On a big library, set ENABLE_SCHEDULED_BUILD_RECOMMENDATIONS=false to skip the nightly build