There are several bits and pieces around that tell you how to get the WordPress cron work properly in simple situations. I just spent a morning getting it all working in a multisite environment so here come my notes on how to get it to work properly.
“Cron” is the scheduler of background tasks. You want to disable the built-in cron simulator when your site has the capability to run the normal UNIX cron jobs. The built-in simulator is quite unreliable and causes problems sooner or later. It is a good thing to have when the normal UNIX cron is not there but if you can install cron jobs you are better off with a standard reliable regular execution of your background tasks.
First of all, the usually advised first step is quite correct whatever the environment. You go to the installation directory, edit your wp-config.php and add the line before that last require_once statement (or anywhere in the middle of the file really) to disable the built-in cron simulator:
/* Disable wp-cron, we run linux cron */
Next, for a site that is not a network, i.e. not a multisite, it is sufficient to add something like this as a cron job:
*/2 * * * * www-data /usr/bin/php /var/www/yoursite/wp-cron.php > /dev/null )
This executes the cron of WordPress every two minutes. If you cannot run the command-line PHP for some reason but have wget (or any other thing, like lynx, curl, whatever) you can add a line to cron to call a URL instead, although that’s going to consume a tiny bit more resources:
*/2 * * * * www-data /usr/bin/wget -q -O - http://yoursite/wp-cron.php > /dev/null
Many recommend adding the parameter “doing_wp_cron” at the end of the URL but that is a mistake. Having that parameter assumes that you already acquired a lock for the cron job execution and may cause problems if you have long running jobs. Without that parameter, the wp-cron will do what it is supposed to do: acquire a lock so there is no contention, and then run its jobs.
For the multisite, however, it does not work so easily. You must execute the wp-cron for each and every of the “sites” in your network separately. This is kinda nuts but that’s how things are. There is no way to do that from a command line (as far as I can tell), so you have to call the URLs at each site.
I have the following script that reads the names of the sites and goes through… --> continue reading →