"Delighted and impressed..."
— Cortland Coleman What They Say

Using a Real WordPress Cron Job for Increased Reliability

Sometimes it is useful to setup a real cron job to ensure that scheduled WordPress core and plugin maintenance gets done. There are things that happen automatically behind the scenes that keep your site running as expected (publishing scheduled posts, for example). This usually works fine but in some cases tasks may not run reliably. Here’s how to solve that.

What is a Cron Job?

I’ll just say this instead of pasting some semi-technical block of text from Wikipedia.

Scheduled stuff happens automatically.

A cron job needs to be setup manually. In most cases, you log into your hosting control panel and schedule a command to be executed at certain times (every 15 minutes, midnight, Tuesdays, etc.). A standard installation of WordPress doesn’t use a real cron job.

Why Use a Real Cron Job?

I’m writing this tutorial because I learned that caching plugins can naturally interfere with WordPress’s ability to automatically run its scheduled tasks. Our Church Content plugin has recurring events (nobody wants to re-enter Sunday Services every week) and I found that the dates on these events were not automatically moving forward every time. I wanted to keep using the caching plugin so the solution was to force the scheduled tasks to run by setting up a real cron job.

Instead of having users setup a real cron job during installation, WordPress has a sort of “virtual cron” feature. Basically the way it works is that you have visitors to your website and periodically one of these visits causes WordPress to ask itself, “should I run some task?” and if the task is due, it runs. This works in most cases but using a real cron job to trigger WordPress tasks is more reliable, especially on low traffic sites (no visitors to trigger tasks) or if you’re using a caching plugin (no trigger since a cached copy is served).

Setup a Real Cron Job for WordPress

I will use cPanel in this example since there is a very good chance your web host uses it. Setting up a cron job with other hosting control panels such as Plesk should be similar (in some cases the feature may be called “Scheduled Tasks” or similar). If your host doesn’t let you manage cron jobs, try a free cron service.

  1. Log into cPanel
  2. Under Advanced, click on Cron jobs
  3. Under Add New Cron Job, choose “Once an hour” for Common Settings
  4. Enter this for Command (changing the URL to match your site):
    wget -O /dev/null http://yoursite.com/wp-cron.php?doing_wp_cron
  5. Click Add New Cron Job

cPanel WordPress Cron

What this does is trigger WordPress’s wp-cron.php script every hour (you can make it more frequent). Any tasks that WordPress has scheduled to run will run (publish a scheduled post, see if my plugin’s recurring events need to be moved forward, etc.). You are no longer relying on WordPress’s “virtual cron” to be triggered upon a site visit.

Disable WordPress “Virtual Cron”

I have not found this to be absolutely necessary but you can do this to disable WordPress’s attempts to run “virtual cron” when visitors access your site. At the very least this will reduce the load on your website. This may be worthwhile for very high traffic sites.

Simply edit your wp-config.php file to add this:

define( 'DISABLE_WP_CRON', true );

What About Multisite Networks?

If you’re running a multisite network installation of WordPress you’ll need to setup a real cron job for each site, including the main network site.

Main Site

The URL to use for the main network site would be:

http://yournetwork.com/wp-cron.php?doing_wp_cron

Subsites

The URL for each subsite would be like one of these, depending on if you use subdirectories or subdomains.

http://yournetwork.com/subsite/wp-cron.php?doing_wp_cron

http://subsite.yournetwork.com/wp-cron.php?doing_wp_cron

You would make a cron job for each subsite in addition to the main network site.

Conclusion

This is usually not difficult to setup but I found few guides out there that I was comfortable linking our customers to, so I wrote this. Hopefully this has been useful to people using caching plugins or that have other reason to force cron to run on WordPress. Please post a comment if you have any suggestions to make this guide more useful.

Related Resources

19 Comments

    • Thanks May. One of the reasons WordPress uses “virtual cron” is because not all hosts provide users with access to cron jobs, so this is handy. I see you can schedule three cron jobs for free. That’s should be enough in most cases.

    • Steve, excuse my ignorance, but what part of the code has to be changed. My Hosting Company has confirmed it has to be the path I enter. Therefore, will the command line be (mywebsite will be replaced with my actual domain):

      wget -O /dev/null /home/sites/mywebsite.com/public_html/wp-cron.php?doing_wp_cron

      Hope you can help

      • Hi Billy,

        wget is for fetching URLs. It sounds like your host doesn’t allow that. I would ask them specifically what to execute. It would probably be something like this (the full path to PHP may be required):

        php -f /home/sites/mywebsite.com/public_html/wp-cron.php > /dev/null

        wget is preferred, though. You might just want to use https://www.setcronjob.com

        • Steve, thanks for getting back. I will keep setcronjob in mind for the future. In the meantime, I went ahead and just implemented the “WP Missed Schedule” plugin to fix the issue of the Missed Schedule alert for scheduled posts.

  1. Thanks for a helpful article Steve. I have a wget cron job running on my site, but it has also been leaving behind a large trail of cron job history/log files… so I have two questions:

    1) is it safe to delete these?
    2) how can I prevent these logs from being saved on my server?

    Any help is much appreciated!
    Thanks.

  2. @scaptal:

    1. Absolutely.
    2. It’s because you’re not doing “wget -qO /dev/null http://site.com/etc“. Specifically the -O /dev/null part which tells it to dump the output basically. The -q is for quiet so you only get an email notification if the wget fails.

  3. Hey, I’ve been trying to do this myself and I’m not having any luck at all. I’ve created a scheduled task which fires off a function and I know that it’s working properly because the function is being triggered when I use the WP “fake” cron jobs (i.e. the ones that relay on site visit). However when I add: define(‘DISABLE_WP_CRON’, true); and setup the real cron job the scheduled task doesn’t fire any more.

    I’ve also tried to use my cron job on a custom file (that sits outside of WP) and it works just fine, as a reference this is what I’m using for the job (in cPanel).

    wget http://madaboutlondon.ru/wp-cron.php?doing_wp_cron=1 > /dev/null 2>&1

    Any idea what I’m doing wrong, it seems to me that the problem is with the way I’m calling the wp-con.php file because I’ve sucessfully verified that the job is scheduled properly, the function works and the cron job is fireing….

    Mika

    • I’d try to access http://madaboutlondon.ru/wp-cron.php?doing_wp_cron=1 to see if it fires. It probably will. If it doesn’t fire via cron automatically then the cronjob is probably not running. Set it up in your hosting control panel to send you the result by email see if something is wrong.

      You could contact your host to see if they see a reason why the cronjob is not executing.

      The WordPress Support Forums may have some insight too: http://wordpress.org/support/

      • Thanks for getting back to me Steve. That’s the weird things you see, it doesn’t fire when I browse that URL directly, don’t get it. Are there any other settings which might interfere with the wp-cron file?

        I can confirm that the task has been scheduled/created/initiated correctly because when i DON’T use define(‘DISABLE_WP_CRON’, true); it fires just fine.

        Mikael

        • I’ve never seen wp-cron.php not fire when accessed directly so that’d be a good question for the WordPress Support Forums.

          Plugin interference is always a possibility (try deactivating all).

        • Ask your hosting company if they disallow running the wp-cron.php from browser. My company is doing it and only with cron is possible. The main problem for me is that if i add a cron task with url /wp-cron.php?doing_wp_cron i get an email with error that file was not found but if i use only /wp-cron.php no errors.

  4. Can i ask what is the difference between running wp-cron.php and wp-cron.php?doing_wp_cron ???
    Cause if i use the second i get an email that says -> Could not open input file: /var/www/vhosts/mydomain.com/httpdocs/wp-cron.php?doing_wp_cron
    With only wp-cron.php i dont get any error but i dont think that it works for missed posts

    • wp-cron.php?doing_wp_cron is not a script and cannot be executed. You would need to use wp-cron.php alone if you’re running the script directly from the command line. Tacking on ?doing_wp_cron is for triggering it via URL, either by browser or a command line using wget, curl or similar.

      wget -O /dev/null http://yoursite.com/wp-cron.php?doing_wp_cron

      I’m not sure how necessary it is to append ?doing_wp_cron when accessing via URL. I haven’t tried without it.

Commenting has been turned off.