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
/scanpage, a metadata refresh on a ROM edit, etc.)
The full table
| Task | Type | Default schedule | Enable var | Schedule/delay var | Purpose |
|---|---|---|---|---|---|
| Scheduled netplay cleanup | Scheduled | */30 * * * * |
- |
- |
Cleans up empty netplay rooms. Always on, not configurable. |
| Scheduled ZIP cache cleanup | Scheduled | 0 4 * * * |
- |
- |
Removes stale cached ZIP files based on tiered TTL. Always on, not configurable. |
| Scheduled upload tmp cleanup | Scheduled | 0 * * * * |
- |
- |
Cleans up orphaned chunked-upload temp directories. 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 rescan | Scheduled | 0 3 * * * |
ENABLE_SCHEDULED_RESCAN |
SCHEDULED_RESCAN_CRON |
Rescans the entire library. |
| Scheduled Switch TitleDB update | Scheduled | 0 4 * * * |
ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB |
SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON |
Updates the Nintendo Switch TitleDB file. |
| Scheduled LaunchBox metadata update | Scheduled | 0 4 * * * |
ENABLE_SCHEDULED_UPDATE_LAUNCHBOX_METADATA |
SCHEDULED_UPDATE_LAUNCHBOX_METADATA_CRON |
Updates the LaunchBox metadata store. |
| 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 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. |
| 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. |
| Sync Folder Scan | Manual | - |
ENABLE_SYNC_FOLDER_WATCHER |
- |
Scan device sync folders for new save files. |
| 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 daily0 */6 * * *: every 6 hours, on the hour*/30 * * * *: every 30 minutes0 2 * * 0: 2 AM every Sunday
Set the env var and restart the container; the scheduler picks up the new schedule the moment RomM comes back up.
Enabling a scheduled task
Most tasks have an ENABLE_* environment variable, like ENABLE_SCHEDULED_UPDATE_LAUNCHBOX_METADATA=true which enables the LaunchBox sync, and every one of them is off by default. 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.
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 shows every task with a "Run" button. Admins (anyone with tasks.run scope) can trigger:
From the API
Monitoring tasks
- Live: Administration → Tasks page shows every task's current status (queued, running, idle, failed).
- API:
GET /api/tasks/statusfor a JSON summary. Wire this to an uptime monitor if you want alerts. - Logs:
docker logs romm→ look forrq.workerlines.
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=1to avoid concurrent scan processes - Enable the watcher but raise
RESCAN_ON_FILESYSTEM_CHANGE_DELAYto 30+ minutes - Disable image conversion if you don't care about WebP (
ENABLE_SCHEDULED_CONVERT_IMAGES_TO_WEBP=false).