There are many things have to be done on background, for instance, version check, update theme, delete posts, delayed posting, delete transients, etc. In WordPress this background job is performed by WP-Cron, witch is defined in wp-cron.php file.
WordPress cron is the system built-in process that handles the scheduling of time-based tasks. Out-of-the-box, WordPress performs a number of scheduled tasks, they include:
- WordPress core update checks
- Plugin update checks
- Theme update checks
- Publishing of scheduled posts
WP-Cron takes its name from cron, which is a time-based job scheduler in Unix-like systems. However, WP-Cron is designed to work on any hosting provider (including shared hosting) without using any external software or tools for scheduling events.
Table of Contents
Problem of WP-Cron
The wp-cron.php is triggered on every http request. If any scheduled event is due, the event is spawned to wp-cron.php for processing, so the event is triggered to run. This is unreliable, espectially for low traffic sites, or heavily cached sites, cause scheduled events to be missed if no traffic is received for a prolonged period of time.
For high-traffic sites, WP-Cron is extremely inefficient. This is because WP-Cron will check for scheduled events on every page load. This could mean that the cron schedules are being checked multiple times per second. This is unnecessary and highly redundant, as scheduled events typically run in minutes or hourly, even monthly interval. Even wp-cron.php creates a lock in WordPress transient, witch stored in wp_options table, but for high traffice sites the high concurrent requests may still spawn multiple requests to wp-cron.php, thus increasing server load.
Disable WP-Cron
To disable WP-Cron, add the following constant to wp-config.php file, witch is under www root folder.
define( 'DISABLE_WP_CRON', true );
This will prevent WP-Cron from automatically checking for scheduled cron events on every page load. In this case all events won't be fired. We have to use system cron utility to fire events.
Schedule jobs in System Cron
The Cron daemon is a built-in Linux utility that runs processes in background at a scheduled time. Linux cron runs continuously and uses the system clock to schedule tasks. This means that scheduled events are never missed.
We can use a Linux cron in conjunction with WP-CLI to reliably schedule events.
cPanel
In cPanel, find Advanced tab and click on Cron Jobs and follow the instruction.
The command parametes:
If you still confuse about the scheduling parameter, please visite https://crontab.guru/ for more detail.
Site Tools
Go to DEVS -> Cron Jobs, follow the instruction to schedule the cron utility.
Enter command as:
cd /usr/local/php71/; php /home/customer/www/hostlike.com/public_html/wp-cron.php
If wget is installed o nhosting server you could use it as:
wget -q -O - https://hostlike.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1
Windows
If the site is hosted on Windows server. You could schedule cron job with PowerShell.
powershell
"Invoke-WebRequest http://YOUR_SITE_URL/wp-cron.php"
Or open Windows Task Scheduler. Select Create Tast ... in the menu
-> Action tab: enter browser location and url to wp-cron.php
-> Trigger tab: enter your schedule for cron to run.
More detail on Windows scheduler, read this on Windows Scheduled Task.
Creating Custom Cron Job
To create and schedule custom cron job we have to use hooks that WordPress provided. WordPress hooks is WordPress API that allow us to ‘hook into’ the build process at certain points and run your custom code. The main function of hooks is to allow you to modify or add features to WordPress without touching the core files.
Create an Action Function
First step is to write an action function that perform certain job for you.
function cron_check_link_availability(){
write_log(" START ");
$time_start = time();
cron_check_link_availability($source);
$time_elapsed = time() - $time_start;
write_log(" END . Time spent: $time_elapsed.");
}
class SomeClass{
static function check_link(){ ... }
}
//call it this way:
add_action($hooker, array('SomeClass', 'check_link'));
Hook to WordPress and Scheduling
Hook with add_action
add_action ( 'hook_name', 'your_function_name', [priority], [accepted_args] );
Read document for more detail regarding the parameters
In my case:
add_action( $hooker, "cron_check_link_availability" );
Schedule with wp_schedule_event
wp_schedule_event( time(), $interval, $hooker, $args );
In my case:
wp_schedule_event( time(), 'five_minutes', $hooker, array('fast_mode' => 0) );
The default interval in WordPress:
-
- hourly
- twicedaily
- daily
- weekly (since WP 5.4)
Define custom intervals:
add_filter( 'cron_schedules', 'cron_interval' );
function cron_interval( $schedules ) {
$schedules['five_minutes'] = array(
'interval' => 5*60,
'display' => esc_html__('Five Minutes')
);
$schedules['ten_minutes'] = array(
'interval' => 10*60,
'display' => esc_html__('Ten Minutes')
);
$schedules['fifteen_minutes'] = array(
'interval' => 15 * 60,
'display' => esc_html__( 'Fifteen Minutes' ),
);
$schedules['twice_hourly'] = array(
'interval' => 30 * 60,
'display' => esc_html__( 'Twice Hourly' ),
);
$schedules['twice_daily'] = array(
'interval' => 12 * 60 * 60,
'display' => esc_html__( 'Twice Daily' ),
);
$schedules['twice_weekly'] = array(
'interval' => 7 * 12 * 60 * 60,
'display' => esc_html__( 'Twice Weekly' ),
);
$schedules['monthly'] = array(
'interval' => 30 * 24 * 60 * 60,
'display' => esc_html__( 'Monthly' ),
);
return $schedules;
}
Avoid adding more than once
if ( ! wp_next_scheduled( $hooker, array('fast_mode' => 0) ) ) {
wp_schedule_event( time(), 'five_minutes', $hooker, array('fast_mode' => 0) );
}
Other steps
Note that the argument is optional based on the action function you created, but the scheduling and checking should keep it consistant, both have it or both none.
Note that 'five_minutes'
is custom interval that defined with filter below.
add_filter( 'cron_schedules', 'cron_check_availability_interval' );
function cron_check_availability_interval( $schedules ) {
$schedules['five_minutes'] = array(
'interval' => 5*60,
'display' => __('Five Minutes')
);
$schedules['ten_minutes'] = array(
'interval' => 10*60,
'display' => __('Ten Minutes')
);
$schedules['fifteen_minutes'] = array(
'interval' => 15 * 60,
'display' => esc_html__( 'Fifteen Minutes' ),
);
return$schedules;
}
Unschedule the event when it is not used. In my case, unregister it when plugin being deactivated.
function remove_checking_job_on_deactivate() {
$timestamp = wp_next_scheduled( $hooker );
wp_unschedule_event( $timestamp, $hooker);
}
register_deactivation_hook( __FILE__, 'remove_checking_job_on_deactivate' );
List WP-Cron Events
you can use the WP Crontrol plugin to view all your current cron jobs in WordPress that have already been scheduled. It’s a great platform for you to have an overview of all the cron jobs lined up for your site. You can verify if the cron schedule working properly from this event list.
In the admin dashboard, click on ‘Cron Event’ option inside the tools. To run the cron event immediately, you simply click the ‘Run Now’ button available alongside action name. You should see WP Cron Events like below.
WordPress provides a simple way to add periodic tasks using hookers. For scheduling a task it is not recommanded to use WP Cron, instead, use system cron for any scheduling tasks.
Comments
This is the perfect blog ffor anybody who hopes to find out about this
topic. Youu definitely put a brand new spin on a topic which has been discussed
for decades.Wonderful stuff, just excellent!