Skip to content

Set up cron

Some of what a classifieds site does cannot happen inside a page request. E-mail alerts have to go out, premium listings have to expire, spam and unactivated accounts have to be cleaned up, and the XML sitemap has to be regenerated. ShopClass runs all of that on a schedule.

Without a working cron, none of it happens. That is the single most common cause of “my alerts never send” and “expired listings are still showing”.

Add one crontab entry on the server and let ShopClass decide what is due:

*/5 * * * * php /path/to/site/oc-cli.php cron >/dev/null 2>&1

That is the whole configuration. The command checks the hourly, daily and weekly tiers each time it runs and executes only what is actually due, so running it every five minutes costs nothing and keeps alerts prompt.

Then turn the fallback off, so work is not attempted twice:

Admin → Settings → General → uncheck Auto-cron.

Over SSH:

Terminal window
crontab -e

Add the line, save, and confirm it registered:

Terminal window
crontab -l

You need the CLI PHP binary, not the web server’s module. If plain php is not on the path, ask your host for the full path — it is often something like /usr/local/bin/php or /opt/alt/php82/usr/bin/php.

The older, explicit form works too, and is what long-running installs already have:

0 * * * * php /path/to/site/oc-cli.php cron --type=hourly
0 3 * * * php /path/to/site/oc-cli.php cron --type=daily
0 4 * * 0 php /path/to/site/oc-cli.php cron --type=weekly

Many shared hosts do not offer SSH but do offer a cron wizard in the control panel (cPanel: Advanced → Cron Jobs; Plesk: Scheduled Tasks). Point it at the same command.

If the panel only allows fetching a URL rather than running a command, use the web entry point instead:

Terminal window
wget -qO /dev/null https://example.com/index.php?page=cron

Set it to run hourly. This is weaker than the CLI — it runs inside a web request and inherits the web server’s timeout — but it is far better than nothing.

If you cannot schedule anything at all, ShopClass can piggyback on visitor traffic instead:

Admin → Settings → General → check Auto-cron.

Due tasks are then triggered by ordinary page views, at most once every five minutes. Nobody waits for them: on PHP-FPM the page is sent first and the work runs afterwards in the same process. On other setups ShopClass falls back to asking itself for ?page=cron over HTTP, which an origin behind a proxy cannot do — it resolves its own public address to the proxy and never reaches itself, so nothing runs and nothing says so. If that is your setup, use a real crontab.

The real cost that remains either way: nothing runs while the site has no visitors.

Use it to get started, then move to a real crontab.

Terminal window
php oc-cli.php doctor

Among its checks, doctor reports cron freshness — how long since the scheduled tasks last completed. If that number keeps growing, your crontab is not running the command you think it is.

Run it manually once to see the output rather than the silence a crontab gives you:

Terminal window
php /path/to/site/oc-cli.php cron --type=hourly
Tier Work
Hourly E-mail alerts, expiring premium listings
Daily Cleanup of expired, spam, blocked and unactivated content; alerts
Weekly Longer-running maintenance

Plugins add their own work to these tiers through the cron_hourly, cron_daily and cron_weekly hooks.

If listings are offloaded to remote storage, the queue that moves uploaded images is drained from the hourly tier — which on a busy site is not often enough, and the hourly tier does too much else to be run every few minutes. Give it a second entry of its own:

* * * * * php /path/to/site/oc-cli.php storage:work --max-seconds=50 >/dev/null 2>&1

This runs the queue worker and nothing else, so a tight schedule is safe. On a site with no remote storage it does nothing and exits cleanly, so it is harmless to add before you need it. See the CLI reference.