Optimizing the WP task scheduler

Certain WP tasks need to be executed in the future, either one time or on an ongoing basis. These tasks include things like publishing a scheduled post  (one-time) and checking for WP, plugin, and theme updates (ongoing). WordPress includes a built-in component called wp-cron.php that triggers execution of these scheduled tasks. But not always when I would want or expect it. It runs on every page or post load. This works fine on a site with a regular stream of moderate traffic.  But …

Optimizing the WP task scheduler

  • If my site is very busy, wp-cron is executed much more often than needed, using up CPU cycles and delaying responses to visitor requests. One of the interweb blogs I checked described it as launching a DoS attack against yourself.
  • If my site is very much not-busy, that is, it has not been visited in a while, scheduled tasks cannot execute and just sort of pile up in a queue. Scheduled posts and auto-updates are delayed. And once my site finally gets some visits, all those queued-up tasks get triggered at once, again potentially causing resource issues and increasing response time.
  • If I use caching – and I use it aggressively – I never can tell when a request will hit my server and trigger wp-cron, as opposed to being served from cache.
  • If I use AWStats – and I do – every call to wp-cron is treated as a pageview, artificially inflating my statistics. I haven’t looked into other web statistics tools but I suspect at least some suffer the same problem. Google Analytics, though, does not count wp-cron as a pageview, and in fact for other reasons tends to under-state statistics.

So, I’d like to optimize WP task-scheduling. Specifically, I’d like it to run on a predictable schedule that I determine. And it turns out I can do so, without too much trouble, and without resorting to another plugin. It is a two-step process.

  1. I use cPanel to setup a server cron job to call wp-cron.php
  2. I disable WP’s calls to wp-cron.php

Curiously, nearly all the guides I found on the interwebs – I looked at quite a few – have these two steps in the reverse order. Nope. I want to set up the server cron job and verify that it seems to be working before I disable WP’s calls.

The beauty of a server cron job is that it does not depend on a user request for a page or post to trigger it. I can schedule it to run at a predictable interval of my choosing – anywhere from once  a minute to once a year in my case. So, what interval should I choose? The suggestions from the interweb guides I reviewed ranged from once a minute to once ever 12 hours. Once an hour seemed to be the most common recommendation and seems like a happy median.

Step First: Setup a server cron job to call wp-cron.php

I logon to my cPanel. I look around – and then use search to find the Cron Jobs feature. In my case it is under Advanced.

I click the icon. The beginning of the dialogue reads… “Cron jobs allow you to automate certain commands or scripts on your site. You can set a command or script to run at a specific time every day, week, etc.” Perfect! Just what I wanted.

But it goes on to offer an ominous … “Warning: You need to have a good knowledge of Linux commands before you can use cron jobs effectively. Check your script with your hosting administrator before adding a cron job.” Ah, OK. Well, I don’t have a good knowledge of Linux commands. And I have no intention of checking with my hosting administrator (it makes me feel weak). So, I proceed with reckless caution.

Further down, the dialogue has a handy drop-down list of Common Settings. I select Once Per Hour. That sets all but the last of the other settings for me.

If I set up several cron jobs I can use the Minute row to stagger them – five minutes apart, for example – so they don’t all execute at the same time.

All that’s left is the actual Command. And … I have no idea what to type there. I scour the interweb guides. Cripes – they offer a number of choices, and most seem overly complicated. The most common suggestion is this, or a variation of it …
wget -q -O - https://mydomain.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1
… and, I can’t seem to get it to work. It attempts to fetch wp-cron.php over https, which doesn’t make a lot of sense to me when the local file system is right there.

I look for something simpler. I find …
cd /home/my-cpanel-username/public_html; php -q wp-cron.php
… and … it seems to work. The -q means ‘quiet’, as in I don’t get an email each time the cron job runs. This is great long-term, but initially I want emails to see if it is working. I remove the -q, and also change the interval from Once Per Hour to Once Per Minute for testing. Ah, the emails look nominal, it seems to be working. I add the -q back in and change back to Once Per Hour.

So, on to …

Step Next: Disable WP’s calls to wp-cron.php

This part is comparatively easy. I just need to add a line to wp-config.php.

I switch over to my cPanel File Manager (I could also use SFTP, except that I don’t use SFTP).  I browse to the file wp-config.php. If I don’t already have a backup of this critical file, I make a backup before I risk editing it. With the backup complete, I click Edit. After the end of the ‘MySQL settings’, that is, immediately after the line that reads ..
define('DB_COLLATE', '');
… I enter
/** Disable WP cron calls */
define('DISABLE_WP_CRON', true);

Save changes, close, that’s it.

WPPOV supports freedom from Net Neutrality and the GDPR. The Internet of the people, by the people, for the people, shall not perish from the Earth.