Calling WP-Cron With an Actual Cron Job

A box of cron flakes.

UPDATE 7/26: This method is not working for me anymore for some reason. Expect a new guide coming soon on an updated method of fixing WP-Cron.

Originally seen on mooey5775.

WP-Cron. It’s one of those things that you love and hate at the same time. Sure, it’s the tool that lets you schedule those posts for the future on your WordPress site. However, the way it’s called reminds me of someone who couldn’t think of anything else with an hour left during a hackathon.

For the people who aren’t familiar with cron, it’s basically a job scheduler in Linux. It’s very flexible, as you can set exactly when and how often you want a job to run, and it WILL run at that time. On the other hand, WP-Cron is somewhat different. When posts are scheduled for the future, actual cron jobs aren’t actually created.

A box of cron flakes.
You know, I’ve always hated waiting to eat.

Instead, WordPress adds your scheduled post or other job to a list of jobs to run. Every time a page is loaded, WordPress checks the list to see if any cron jobs need to be run. If a cron job needs to run, WordPress will call the cron job in the background while bringing you to your content. This has many potential problems in both a low traffic and high traffic site.

Low traffic sites usually don’t see many page views, which means the cron jobs don’t get executed when they should. Got a backup job that needs to be run? Too bad. Wait until someone (or yourself) tries to access your site.

High traffic sites get too many views. Sometimes, WP-Cron can be executed too many times, decreasing server performance and increasing the likelihood of your server crashing.

However, in WordPress’ defense, this system was created to maximize compatibility with all systems. Well, WordPress never ran very well on Windows anyway (Ha! IIS? What a joke).

Luckily for us, there’s a way to change the method of calling WP-Cron! WP-Cron can be called RESTfully by accessing the URL where it lives:

http://{your_site}/wp-cron.php?doing_wp_cron

Luckily for everyone, we can use wget to call this from the command line. Before we begin, make sure you have some method of accessing your crontab (if you can access a command line, you should be fine). Also, make sure you’re running some kind of Linux/Unix and have wget installed. Generally, you can find if you have wget by running this command and seeing if it spits anything out:

which wget

If it returns anything, than you have wget. If it doesn’t, install it with your local and friendly package manager. All set? Let’s move on. The first thing we want to do is stop WordPress from calling cron. You can do this by editing your wp-config.php file, which should be located in your site root. Simply add this line:

define('DISABLE_WP_CRON', true);

And you should be all set with that. Next, you’re going to want to set up an actual cron job to call WP-Cron. To do this, we’re going to want to edit the crontab. Most Linux users can do this by running crontab -e.

You’re going to want to add this line (all on one line), then exit and save:

*/15 * * * * wget -q -O - http://{your_site}/wp-cron.php?doing_wp_cron > /dev/null 2>&1

Let’s break down what this does. The first part, */15, runs the cron job every multiple of 15 minutes in an hour (15, 30, 25, 0, etc.). This seems to strike a good balance between overloading your server and not having anything run at all. Theremaining stars basically tell cron to run it regardless of the hour, day, week, month, etc. wget is where the command starts. -q means quiet mode, which turns off wget’s output. -O – means to output the contents of wp-cron.php that it just downloaded. We’ll be taking care of the output later. The URL is where to send a request (obviously replace {your_site} with your site). The > means that we’re going to send the output to a file. /dev/null is the “file” that we’re sending wp-cron.php to. It’s basically like a black hole in your system, destroying everything that comes into it. We don’t actually need the contents of the file that we downloaded, so away it goes. 2>&1 basically combines the log output and the error output of the command into one pipe.

And that’s it! To test it, schedule a post on your site a few minutes in the future and refresh your browser when a quarter of an hour passes. Marvel in the timeliness of your posts.

Leave a Reply

Your email address will not be published. Required fields are marked *