Scheduled Tasks
jekcms does its background work through a single entry point: cron.php. Every tick it takes a lock (so overlapping runs skip instead of colliding), walks a fixed list of built-in duties, and processes the one-off task queue. You don't configure the duties — they ship with the product and guard themselves (each one checks whether it has anything to do before doing it).
This page covers what runs, how tasks get queued, and how to trigger the runner. If you can't (or don't want to) set up real cron, see Cron Setup — scheduled publishing also works without any cron via the built-in visitor-triggered scheduler.
Built-in duties
Each cron.php run works through these, in order:
- Publish scheduled posts — posts whose publish time has passed go from
scheduledtopublished - One-off task queue — pending rows in the
scheduled_taskstable are executed (see below) - Content queue — due items in the Content Studio queue are published, and the queue is topped up when auto-sync is on
- Session cleanup — expired sessions are removed
- Automatic maintenance — cache/log maintenance according to your Settings choices
- Cache cleanup — stale cache entries are purged
- Social/webhook queue — pending outgoing queue items are processed
- Sitemap refresh —
sitemap.xmlis rebuilt when posts changed since the last build
The run's outcome is returned as JSON (one entry per duty: success, count, error), so you can read the response of a manual trigger to see exactly what happened.
The one-off task queue
The scheduled_tasks table is a lightweight job queue: each row has a type, a JSON payload, a scheduled_at time and a status (pending → processing → completed/failed, with error_message kept on failure). Supported types include email, webhook (POST a payload to a URL), social_post, pinterest_post, ai_content, fetch_trends, generate_video and cleanup.
Rows are created by product features — for example Content Studio's panel queues content_generation jobs — and you can reschedule or drop pending items from those screens. There is no separate task-management UI; the queue is an implementation detail those features share. Developers can insert rows directly (same columns as above) and the next cron tick will pick them up.
Triggering the runner
Two ways:
- CLI (what real cron should call):
php /path/to/admin/cron.php
- HTTP — define
CRON_SECRETin your config, then:
https://yoursite.com/admin/cron.php?key=YOUR_CRON_SECRET
Without a valid key the endpoint answers 403 Access denied. This is handy for external cron services (cron-job.org and the like) on hosts without shell access.
Setting up cron
cPanel / hPanel
Advanced → Cron Jobs → Add New Cron Job:
*/5 * * * * /usr/bin/php /path/to/admin/cron.php >/dev/null 2>&1
Replace /path/to/ with your install root. Some hosts need the full PHP binary path — run which php in the shell, or try /usr/local/bin/php.
Plain Linux (crontab)
crontab -e
Add:
*/5 * * * * cd /var/www/jekcms && /usr/bin/php admin/cron.php >> logs/cron.log 2>&1
Windows Task Scheduler
Create a basic task → trigger daily, repeat every 5 minutes, duration 24 hours → action: start C:\xampp\php\php.exe with argument C:\xampp\htdocs\jekcms\admin\cron.php.
Verifying cron is actually running
Trigger the HTTP endpoint once with your CRON_SECRET and read the JSON: every duty reports success or an error. If real cron seems dead, check:
- Is the cron job installed?
crontab -l - Is the PHP binary path correct?
- Any error output? Redirect to a log file (drop the
>/dev/null) and read it - Remember: when no real cron runs, the visitor-triggered scheduler still publishes scheduled posts — see Cron Setup