Creating Cron jobs in WordPress plugins

This topic has been covered plenty already but I always find myself googling this or looking at an old codebase when I need to create cron jobs in WordPress.

So this is more of a note to self (as I imagine many future posts will be) of how to do this as a self contained example, in a WordPress plugin.

Here’s the code, with comments:

// Setup the interval/frequency for the cron job.
add_filter( 'cron_schedules', 'rm_codes_cron_schedules' );
function rm_codes_cron_schedules( $schedules ) {
	// Create a 12hrs interval.
	if ( ! isset( $schedules['12hrs'] ) ) {
		$schedules['12hrs'] = array(
			'interval' => DAY_IN_SECONDS / 2,
			'display'  => __( 'Once every 12 hours', 'rm-codes' ),
	return $schedules;

// Attach the cron job setup to plugin activation
register_activation_hook( __FILE__, 'rm_codes_cron_activate' );

// Setup the cron job to run at the specified interval.
function rm_codes_cron_activate() {
	// If the cron job is not scheduled, schedule it.
	if ( ! wp_next_scheduled( 'rm_codes_cron' ) ) {
		wp_schedule_event( time(), '12hrs', 'rm_codes_cron' );

// Remove the cron job when the plugin deactivates.
register_deactivation_hook( __FILE__, 'rm_codes_cron_deactivate' );

// Deactivate the cron job.
function rm_codes_cron_deactivate() {
	wp_clear_scheduled_hook( 'rm_codes_cron' );

// Add the cron job task action.
add_action( 'rm_codes_cron', 'rm_codes_cron_run_task' );
// The task to run.
function rm_codes_cron_run_task() {
	// Run the task...
	// ** error_log() won't usually work in cron for debugging,
	// better use file_put_contents.
	file_put_contents( WP_CONTENT_DIR . '/debug.log', 'Cron job ran at ' . gmdate( 'M d Y H:i:s' ) . PHP_EOL, FILE_APPEND );

Remember, don’t do anything time critical with WP Cron as it will only be run when a visitor hits your site and the interval has passed.

For further reading checkout the docs on WP Cron.