Repository navigation
Scheduler
oCMS includes a built-in cron scheduler that manages periodic tasks across the core system and modules. The scheduler admin UI provides a centralized interface to view, manage, and manually trigger scheduled jobs.
The scheduler manages three types of jobs:
- Core jobs — Built-in system tasks (e.g., publishing scheduled pages)
- Module jobs — Tasks registered by installed modules (e.g., analytics reporting, data cleanup)
- Custom tasks — Scheduled HTTP GET requests that administrators create in the admin UI (see Custom Tasks)
Built-in jobs:
| Source | Name | Default schedule | Description |
|---|---|---|---|
core |
scheduled_pages |
* * * * * (every minute) |
Publish pages scheduled for publishing |
core |
demo_reset |
0 1 * * * (daily at 01:00 server time, UTC on Fly.io) |
Only in demo mode: reset the demo data and restart; no manual trigger |
task |
cleanup |
0 3 * * * (daily at 03:00 server time) |
Delete custom-task runs older than 30 days |
Each job has:
- A default schedule (cron expression)
- An optional override schedule (persisted to database)
- Timing information (last run, next run)
- Optional manual trigger capability
Navigate to /admin/scheduler (admin only) to view all scheduled jobs:
| Column | Description |
|---|---|
| Job | Job description and internal name |
| Source | Origin (core or module name) |
| Schedule | Current cron expression (or override) |
| Last Run | When the job last executed |
| Next Run | When the job will execute next |
| Actions | Edit, reset, or trigger buttons |
The Source column uses color-coded badges:
- Indigo — Core system job
-
Green — Custom task (
task) - Cyan — Module job
Click the Edit button to change a job's cron schedule:
- A modal dialog appears with the job name and current schedule
- Enter a new cron expression
- Click Save — The new schedule takes effect immediately
The system validates the cron expression before applying it. An invalid expression is rejected and the current schedule stays in place.
oCMS uses standard cron syntax with support for shorthand intervals:
| Expression | Meaning |
|---|---|
* * * * * |
Every minute |
0 * * * * |
Every hour at :00 |
0 1 * * * |
Daily at 01:00 |
0 1 * * 0 |
Weekly (Sundays at 01:00) |
0 0 1 * * |
Monthly (1st of each month) |
@every 1h |
Every 1 hour (interval) |
@every 6h |
Every 6 hours (interval) |
@every 30m |
Every 30 minutes (interval) |
5-Field Cron Fields:
- Minute (0-59)
- Hour (0-23)
- Day of Month (1-31)
- Month (1-12)
- Day of Week (0-6, 0=Sunday)
Use * to match any value in a field.
- Publish scheduled pages every 5 minutes:
*/5 * * * * - Run analytics export daily at 2:00 AM:
0 2 * * * - Sync data every Sunday at noon:
0 12 * * 0 - Cleanup old logs every 6 hours:
@every 6h
If a job supports manual triggers, a Run Now button appears. Click it to execute the job immediately (outside its normal schedule).
Manual triggers:
- Execute immediately, bypassing the cron schedule
- Log the trigger event with the user who initiated it
- Do not reset the job's schedule or timing counters
Not all jobs support manual triggers. Jobs that require specific timing conditions may not allow manual execution.
If a job's schedule is overridden, a Reset button appears. Click it to:
- Remove the override from the database
- Restore the default schedule immediately
- Update the cron job with the default timing
When you edit a job's schedule, the override is persisted to the database:
- Overrides survive application restarts
- Each job has at most one override
- Overrides are deleted when the schedule is reset
- On startup, the scheduler loads and applies all overrides automatically
The Custom Tasks section lets administrators schedule an HTTP GET request to a URL (New Task). A task has a name (3-100 characters), a URL (at most 2048 characters; https only when OCMS_REQUIRE_HTTPS_OUTBOUND is on, the default in production), a cron or @every schedule, and a timeout of 1-300 seconds (default 30).
Each task can be edited, enabled or disabled, run immediately (one manual run per 10 seconds per task), deleted together with its run history, and its runs inspected (status, HTTP status code, duration, error). Active tasks also appear in the jobs table with source task.
- URLs that resolve to private, loopback, link-local or other reserved addresses,
localhostand cloud metadata hosts are rejected when the task is saved, before every run, and on every redirect. - The response body is not stored; a run records only the content type and byte count.
- Runs older than 30 days are deleted daily by the
task:cleanupjob.
When demo mode is enabled (see Module: Demo Mode), scheduler modifications are disabled:
- View all jobs and schedules
- Cannot edit job schedules
- Cannot reset schedules
- Cannot trigger jobs manually
- Cannot create, edit, enable/disable, delete or run custom tasks
Scheduler events are logged in the audit trail at /admin/events:
- Schedule updated — Job's cron expression changed
- Schedule reset — Override removed
- Job manually triggered — Job executed manually
- Scheduled task created / updated / enabled / disabled / deleted / manually triggered — Custom task changes
Each event includes the user, job source/name, new schedule, client IP, and request URL.
Pages scheduled for publishing are picked up every minute by default. If that is more than you need:
Default: * * * * * (every minute)
Override: */5 * * * * (every 5 minutes)
Set its schedule to an impossible expression:
0 0 31 2 *
(February 31 doesn't exist). For a custom task, use Disable instead.
Move a job away from your backup window:
Current: 0 2 * * * (daily at 2:00 AM)
Override: 0 4 * * * (daily at 4:00 AM)
- Check the cron expression is valid
- Verify the job's source module is active (for module jobs)
- Ensure the application is running (jobs run in-process)
- Check application logs for execution errors
- Job may not support manual triggers
- Check application logs for the specific error
- Verify the job's source module is loaded
- Verify database write permissions
- Check application logs for database errors
- Restart the application to re-apply overrides
Getting Started
Core Features
- Content Management
- Media Library
- Taxonomy
- Menu Builder
- Forms
- Multi-Language
- SEO
- Feeds
- Video Embedding
- Agent-Ready
Administration
API & Integrations
Security
Theme Development
Module Development
Built-in Modules
- Module: Sentinel
- Module: Developer
- Module: DB Manager
- Module: Migrator
- Module: Informer
- Module: Demo Mode
- Module: Internal Analytics
- Module: External Analytics
- Module: Privacy
- Module: Embed
- Module: MCP Server
Deployment