Disable WP-Cron in WordPress
What is WP-Cron?
WP-Cron is the way that WordPress executes scheduled jobs that are added via
wp_schedule_event() or one of its associated functions. First it’s a bit of a hack given the single threaded-ness of PHP. It’s simply not possible to spin up a
Thread like you would in Java to do the work asynchronously, and we don’t want the users to have to wait while we run a large job. To get a around this WordPress checks to see if there are any scheduled jobs with an execution time in the past (more on this in a bit), and will then make a request to itself calling
wp-cron.php with a querystring of
doing_wp_cron. The job can now run in this new request (which is a different PHP process) and the page HTML is returned to the users without ever trying to fetch the results.
What’s good about WP-Cron?
WP-Cron lets you do things like check for plugin updates or other arbitrary tasks at set intervals – once or twice a day, longer, or more frequently if you desire. In many ways this mimics the functionality of
cron on your Linux box.
There are lots of useful things you can do with a scheduled task – send emails, update derived database values, really anything that you want to happen regularly, but not on every request. If you’re ok with some user’s seeing slightly stale data in exchange for better performance, you can use a WP-Cron job to indicate that the cache needs to be primed.
What’s bad about WP-Cron?
While WP-Cron can be a very useful tool, there are some downsides to it as well. As mentioned earlier it can only check for jobs that should have already run, meaning that the scheduled
$execution_time < time(), but this can be an issue on sites with low traffic, especially if you actually care what time the task will be run. Even if your site does decent traffic during the day, maybe it drops way off at night and you want to run something as close to 1:00AM as possible… which might or might not happen.
There is also the performance hit you take making an HTTP request, even though it’s to yourself. Why check the database and WP-Cron locks to see if the HTTP request is even necessary? Speaking of locks – while much better about locking WP-Cron, sites with heavy traffic can occasionally end up with multiple WP-Cron requests (if user requests come in at the exact same time).
How to disable WP-Cron?
The way that I handle WP-Cron on my sites is to disable it entirely by setting the
DISABLE_WP_CRON constant to
wp-config.php. This will prevent WordPress from checking for WP-Cron tasks at all when a user makes a request.
The next step is to set cron on the system to make the request to wp-cron.php based on whatever schedule works best for you. You can have it run as frequently as once per minute, or up to… forever. Probably whatever the smallest resolution of your recurring tasks are is best, unless you are using
wp_schedule_single_event() to run something asynchronously – then a minute might be best.
Disable WP-Cron in wp-config.php
define( 'DISABLE_WP_CRON', true );
Schedule WP-Cron using crontab
# Run WP-Cron every 5 minutes */5 * * * * /usr/bin/curl --silent http://example.com/wp-cron.php?doing_wp_cron >/dev/null