Tutorial · wordpress · Published 2026-08-16 · 3 min read

Setting up real cron for WordPress

Move WordPress from wp-cron.php visiting-triggered scheduling to a real server cron so scheduled jobs and email run reliably.

Confirm what is running today

WordPress ships with `wp-cron.php` and, by default, triggers it from visits: on each page load the request checks for due events and, if any are owed, makes an internal request to run them. That is reliable enough on a busy site but fragile on a quiet one, because no visits means no cron. The first step of a real-schedule setup is to confirm whether the visiting trigger is still on.

Check from the command line whether the constant that disables it is set anywhere:

wp config get DISABLE_WP_CRON

If the command returns nothing, DISABLE_WP_CRON is not defined and the site is still relying on visiting-triggered cron. Toggle a real scheduler on before you flip that constant, or your scheduled posts, email queues and plugin updates will silently stop. See the wp-cron troubleshooting article for the full diagnostic if an event is already failing.

Add the server job

Open the constant in wp-config.php, above the `/* That's all, stop editing! */` line:

define( 'DISABLE_WP_CRON', true );

Then create the scheduled task on the server. In cPanel this is Cron Jobs; on a VPS it is a crontab entry. A job that wakes WordPress every few minutes and processes whatever is due is the goal:

*/5 * * * * cd /home/example/public_html && wp cron event run --due-now

Using wp cron event run --due-now through WP-CLI is the most robust option because it runs the due events directly through the WordPress bootstrap without a web request. If WP-CLI is not available, a curl to the web endpoint is the fallback:

*/5 * * * * curl -s https://example.com/wp-cron.php >/dev/null 2>&1

Either approach removes the dependency on visitor traffic. The WordPress performance settings article covers why removing the visiting-triggered spawn from page loads is also a small performance win on busy sites.

Verify events fire on time

After the job is in place, confirm events stop backing up and start firing on schedule:

wp cron event list --fields=hook,next_run_relative,status

Due events should show a fresh next run on every poll, rather than a pile of past-due entries. Test the real trigger by creating a scheduled test post set a minute out and watching it publish without any visits. Keep the interval at five minutes or less for good fidelity; anything longer reintroduces delays similar to the visiting-triggered behaviour you replaced. If an update or plugin change later breaks the loopback, the update failures article is a good first stop.

Need a website built, fixed, optimised, migrated or replaced?

This technical resource is written by CSMBAC, a small design and development studio. If you would rather hand the problem to a professional, the website service page explains how we build enquiry-ready websites.

Explore website services