Cron Your WordPress! How to Set Up Cron Jobs Without Any Plugins (Examples Included)
Table of Contents
- Tech Used
- Reliable Cron Setup for WordPress
- What Are Cron Jobs
- When WP-Cron Runs
- False Positives
- The Solution
- Testing if WP-Cron.php Works
- Time to complete: 15-30 minutes
- Difficulty: Intermediate
- cPanel hosting account with Cron support
- Working installation of WordPress 4.4.13*
*should work with any other version as well
Reliable Cron Setup for WordPress
There are some tutorials out there, offering different answers to that question. Since different web hosting companies set up their servers differently, things tend to work. Until they don’t.
What I wanted was a command that would trigger WordPress’ cron and that would be the most native syntax there is, so it would work on any Linux host.
If you have already spent enough time googling, to the point where you question your sanity, you might be better off reading from “False Positives” onward.
If you want some sort of foundation to what you are doing, tag along!
What Are Cron Jobs
Simply put, cron is the app for Unix-based systems (such as Linux) that is used for executing a command at a specific time. That would be a time interval of days, hours, minutes and seconds that you can explicitly specify.
Cron can also run in cycles. Such as: every day, every hour, every minute and every second. Great for triggering commands routinely. Such as scheduling posts in WordPress.
Okay but what does a “Cron job” mean? – you ask.
Once you schedule a task (ex. “launch program X”) via cron, it adds an entry to an internal schedule. And that entry is called a cron job.
Since some web hosting companies don’t offer cron jobs (although I am yet to stumble upon one) the folks at WordPress have created an internal cron scheduler.
That means it is available within WordPress. In case you are wondering – it is located in the root directory of your WP installation. Right next to wp-config.
When WP-Cron Runs
This is where things get tricky and a lot of people who want reliability in scheduling prefer to switch to the host’s regular cron.
WordPress is just a big php script that runs everytime a page is requested by a visitor on your website. This “script” includes everything you can think of: from loading plugins, displaying website content to checking for updates and other scheduled tasks.
Or simply put:
Wp-Cron runs every time someone sends a request to your site.
While an internal cron is nice, it comes as a one-size-fits-all solution. If we crudely separate websites into 2 main categories – big sites and small websites, we can easily see where it falls short.
Small Web Sites
If you don’t have people visiting your website every minute, you cannot rely on WP-Cron to publish that awesome new article you had scheduled in the exact, intended moment.
Having your article out of schedule, can lead to a bunch of problems with your marketing plan, most commonly – having your scheduled social media posts link to non-existing content.
Big Web Sites
Big web sites have plenty of visitors, so a missed schedule is a rarity. However, going big brings other problems to the table. Resource on your host tend to get precious. You might not want to have a check for scheduled cron jobs run every few seconds. Or even worse – few times per second.
Before providing the actual solution, here are cron commands that either worked on one host and didn’t on another or don't work at all.
Just to make crystal-clear what I am talking about here – when you log in to your hosts cPanel → cron Jobs, the content you enter in the Command field is either:
1) http://yoursite.com/wp-cron.php 2) http://yoursite.com/wp-cron.php?doing_wp_cron 3) php http://yoursite.com/wp-cron.php 4) /usr/local/bin/php /home/cpanelUserName/public_html/wp-cron.php
worked on one host and stopped on another
same as 1.)
didn’t work as well
4 commands, 0 success.
WordPress is written in PHP which runs on Unix/Linux web hosts. Therefore I needed the most appropriate command for a Unix system and something that would be independent as to how the local environment is set.
We first call the PHP intepretator:
and then we add the local path to the script it should run:
Local path because we tell the OS to do something. Absolute path would be for addressing something outside the server.
And the full command would be:
I like this one as it would call the PHP interpretator regardless of where it is located (unlike command #4 on the list above).
But that didn’t work as well!
What I didn't realize all along is that WP-Cron checks for $_GET attributes, so it would require HTTP call in order to work. Although the command above is valid, the call is done through a local path.
For this reason we need to have a PHP script that calls WP-Cron through HTTP and then call it through a regular cron command.
So, create a file such as “cron-do.php” in the root directory of your website and add/edit the following code:
<?php $result = file_get_contents('http://yoursite.com/wp-cron.php?doing_wp_cron'); echo $result; ?>
Basically, this sends an HTTP request to the WP-Cron file with a $_GET attribute. Just what we need!
Now head to your host's cPanel → cron Jobs and create a new cron job. Specify the frequency you want it running and in the Command field add the following:
One More Thing
If you are using a newer version of WordPress you might want to double-check you have set your timezone right. You can do so by going WP-Admin → Settings. Depending on the language of your WordPress select either a UTC timezone or a major city corresponding to a UTC timezone.
Testing if WP-Cron.php Works
How Not to Test WP-Cron.php
Create a new cron job that runs every minute.
Head to your WP-Admin → Posts and add a new post.
Use “Test” for title and content of the post, then schedule it one or two minutes from now.
Return to the Posts screen and start refreshing around the time of the scheduled post.
The Actual Way
There is one little detail that fails the test above. It was what first came to my mind, so that's why I decided to leave it as an example.
It's step #4 that breaks the test. That's because you are actually triggering wp-cron.php every time you do a page request.
According to an awesome article on WordPress initialization3, the best way to test for post scheduling is through the RSS feed. WordPress loads wp-cron.php several files after the RSS feed, so if you are requesting the feed, Cron won't load.
Here are the steps:
- Cron job running every minute
- Add a new post
- Schedule it a minute from now
- Close the tab with WP-Admin
- Visit yoursite.com/feed
- Locate that latest post in the XML tree
- Keep refreshing every few seconds until your scheduled post appears
© 2018 ItKnol