View Categories

Cron Jobs & Background Worker

4 min read

Academy & Exam OS does time-based and deferred work in console commands that your hosting scheduler (cron) runs. Without them, expired test attempts are not sealed, grading and exports wait, online payments are not reconciled and announcements are not delivered.

Prerequisites: an installed site, and a hosting plan that can run PHP from the command line every minute with the same PHP 8.3 or 8.4 and the same extensions as the website.

The commands #

Run them from the Web/ folder (the folder that holds bin/, config/ and webroot/).

ScheduleCommandWhat it does
Every minutephp bin/console.php workerSeals attempts whose deadline passed, grades queued attempts, produces question exports, processes app jobs, and reconciles open online payments and pending refunds with Stripe / Razorpay / PayPal
Every minute (or every few minutes)php bin/console.php worker --kind=communication --limit=25Delivers Communication Hub announcements (in-app and e-mail); --limit is 1–100 deliveries per run
Optional, every few minutesphp bin/console.php worker --kind=payments --limit=25Payment reconciliation only, if you want it on its own schedule
Hourly — Single Site and Multi Site onlyphp bin/cake.php license renewConfirms the software licence when a renewal is due

Each command makes one finite pass and exits; none of them runs permanently. Overlapping runs are safe: two workers never process the same item.

Write the licence command exactly as shown, with bin/cake.php. bin/cake without .php is a shell script: php bin/cake license renew only prints that script and never runs the renewal. If you scheduled that form from an earlier version of this guide or of the installer’s success page, change it.

Add the cron jobs in a hosting panel #

Shared-hosting panels (for example cPanel Cron Jobs or hPanel Advanced → Cron Jobs) accept the commands with the full path to the file. Replace /path/to/site with the folder that holds the application’s bin/, config/ and webroot/ — the folder you uploaded the contents of Web/ into.

ScheduleCommand to enter
Every minute (* * * * *)php /path/to/site/bin/console.php worker
Every minute (* * * * *)php /path/to/site/bin/console.php worker --kind=communication --limit=25
Hourly (15 * * * *) — Single Site and Multi Sitephp /path/to/site/bin/cake.php license renew
  1. Open your panel’s cron job section.
  2. Choose a custom command cron type, so that the PHP binary you enter is the one that runs.
  3. Add each job from the table above with the schedule shown.
  4. Save, wait a minute or two, and check the result (see Check that the worker runs below).

Important: Use the command-line PHP binary that matches the PHP version you selected for the website. On shared hosting, the default php or /usr/bin/php, and a panel’s “PHP” cron type, can run an older PHP. The job then fails before the application starts and shows the reason only in the cron output. Your host’s documentation or support names the version-specific binary.

Example — Hostinger shared hosting: on a tested account whose website ran PHP 8.3, /usr/bin/php ran PHP 8.2 without sodium, and the hPanel “PHP” cron type also used PHP 8.2, so the jobs never started. A “Custom” cron job with the PHP 8.3 command-line binary worked:

/opt/alt/php83/usr/bin/php /home/<account>/domains/<your-domain>/public_html/<site-folder>/bin/console.php worker

This path is specific to Hostinger and to the PHP version selected. It is an example, not a requirement for other hosts. To check which PHP a cron job uses, schedule php -v once with the same binary and read the job’s output in the panel.

If the panel refuses shell characters #

Some panels do not accept >, 2>&1 or && in the command field. Put the commands in a small script, upload it (ideally outside the public web folder) and schedule /bin/sh /path/to/worker.sh every minute:

#!/bin/sh
php /path/to/site/bin/console.php worker >> /path/to/site/logs/worker-cron.log 2>&1
php /path/to/site/bin/console.php worker --kind=communication --limit=25 >> /path/to/site/logs/worker-cron.log 2>&1

Add the cron jobs on a VPS (crontab) #

* * * * *  cd /var/www/academy/Web && php bin/console.php worker >> /var/log/academy-worker.log 2>&1
* * * * *  cd /var/www/academy/Web && php bin/console.php worker --kind=communication --limit=25 >> /var/log/academy-hub.log 2>&1
15 * * * * cd /var/www/academy/Web && php bin/cake.php license renew >> /var/log/academy-license.log 2>&1

The last line applies to Single Site and Multi Site only.

Run the jobs under the same user as the web server (or a user in the same group with write access to Web/tmp/, Web/logs/ and Web/storage/) — never as root. The worker reads Web/config/app_local.php, so that file must be readable by that user.

Check that the worker runs #

  • Communication Hub: queued announcements are delivered within a minute or two. A queue that never drains means the communication worker is not running.
  • Mock Tests: results of timed tests that ended are released only after the worker has sealed and graded them.
  • Orders & Payments: an online order that stays Awaiting payment long after the student paid, with no provider events listed, means webhooks are not reaching the site; the worker still confirms it on a later pass.
  • Logs: each pass prints one summary line (for example Processed n grading jobs and n exports.). Redirect the output to a log file as in the examples above.

Maintenance mode #

Create the file Web/storage/maintenance.flag to put the site into maintenance: every request answers 503 Service Unavailable with a retry hint, while /healthz keeps answering for uptime monitors. The worker does not start work while the flag exists. Delete the file to leave maintenance mode.

Related documents #

Watch the Video Tutorial #

The “Cron jobs” part of Academy & Exam OS Video Tutorial 02: First-Time Setup & Licence Activation shows this (watch from 3:39 on YouTube). All Academy & Exam OS video tutorials.