Created
April 9, 2026 19:29
-
-
Save vapvarun/92217323ff84ed1ce587794b999bbee2 to your computer and use it in GitHub Desktop.
WordPress Cron Jobs Explained: Schedule Tasks Without Server Access (wppioneer.com)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Schedule a custom cron event on plugin activation. | |
| * | |
| * Hooks into 'wp_schedule_event' to register a task that runs | |
| * once every hour starting from the current time. | |
| */ | |
| function myplugin_activate() { | |
| if ( ! wp_next_scheduled( 'myplugin_hourly_event' ) ) { | |
| wp_schedule_event( time(), 'hourly', 'myplugin_hourly_event' ); | |
| } | |
| } | |
| register_activation_hook( __FILE__, 'myplugin_activate' ); | |
| /** | |
| * The callback that fires when the cron event runs. | |
| */ | |
| add_action( 'myplugin_hourly_event', 'myplugin_do_this_hourly' ); | |
| function myplugin_do_this_hourly() { | |
| // Your scheduled task logic goes here. | |
| error_log( 'myplugin_hourly_event fired at ' . current_time( 'mysql' ) ); | |
| } | |
| /** | |
| * Clean up the scheduled event on plugin deactivation. | |
| * Always do this — orphaned cron entries slow every page load. | |
| */ | |
| function myplugin_deactivate() { | |
| $timestamp = wp_next_scheduled( 'myplugin_hourly_event' ); | |
| if ( $timestamp ) { | |
| wp_unschedule_event( $timestamp, 'myplugin_hourly_event' ); | |
| } | |
| } | |
| register_deactivation_hook( __FILE__, 'myplugin_deactivate' ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Register custom cron intervals. | |
| * | |
| * WordPress ships with 'hourly', 'twicedaily', and 'daily'. | |
| * Use this filter to add any interval your plugin needs. | |
| */ | |
| add_filter( 'cron_schedules', 'myplugin_add_cron_intervals' ); | |
| function myplugin_add_cron_intervals( $schedules ) { | |
| // Every 15 minutes | |
| $schedules['every_fifteen_minutes'] = array( | |
| 'interval' => 15 * MINUTE_IN_SECONDS, // 900 seconds | |
| 'display' => __( 'Every 15 minutes', 'myplugin' ), | |
| ); | |
| // Every 6 hours | |
| $schedules['every_six_hours'] = array( | |
| 'interval' => 6 * HOUR_IN_SECONDS, // 21600 seconds | |
| 'display' => __( 'Every 6 hours', 'myplugin' ), | |
| ); | |
| // Weekly | |
| $schedules['weekly'] = array( | |
| 'interval' => WEEK_IN_SECONDS, // 604800 seconds | |
| 'display' => __( 'Once a week', 'myplugin' ), | |
| ); | |
| return $schedules; | |
| } | |
| // Now register an event with your custom interval: | |
| function myplugin_schedule_custom() { | |
| if ( ! wp_next_scheduled( 'myplugin_fifteen_min_event' ) ) { | |
| wp_schedule_event( time(), 'every_fifteen_minutes', 'myplugin_fifteen_min_event' ); | |
| } | |
| } | |
| add_action( 'wp', 'myplugin_schedule_custom' ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Step 1 — Add this constant to wp-config.php to disable WP-Cron. | |
| * | |
| * Place it ABOVE the "That's all, stop editing!" line. | |
| */ | |
| define( 'DISABLE_WP_CRON', true ); | |
| /* | |
| * Step 2 — Add a real server cron job via crontab. | |
| * | |
| * Run: crontab -e | |
| * | |
| * Then add one of the following lines: | |
| * | |
| * Every minute (recommended for busy sites): | |
| * * * * * * php /var/www/html/wp-cron.php > /dev/null 2>&1 | |
| * | |
| * Or using WP-CLI (preferred — bootstraps WordPress properly): | |
| * * * * * * wp cron event run --due-now --path=/var/www/html --quiet | |
| * | |
| * Every 5 minutes (for lighter sites): | |
| * *\/5 * * * * php /var/www/html/wp-cron.php > /dev/null 2>&1 | |
| * | |
| * Replace /var/www/html with the actual path to your WordPress root. | |
| * For WP-CLI, make sure wp is in the system PATH or use the full path: | |
| * /usr/local/bin/wp cron event run --due-now --path=/var/www/html --quiet | |
| */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Debug helper: list all scheduled WP-Cron events with their | |
| * next run time and recurrence interval. | |
| * | |
| * Drop this in a plugin or a quick throwaway file, then visit | |
| * your site as an admin. Remove it after debugging. | |
| */ | |
| add_action( 'admin_notices', 'myplugin_debug_cron_events' ); | |
| function myplugin_debug_cron_events() { | |
| if ( ! current_user_can( 'manage_options' ) ) { | |
| return; | |
| } | |
| $crons = _get_cron_array(); | |
| if ( empty( $crons ) ) { | |
| echo '<div class="notice notice-info"><p>No cron events scheduled.</p></div>'; | |
| return; | |
| } | |
| echo '<div class="notice notice-info" style="overflow:auto;max-height:400px;">'; | |
| echo '<p><strong>Scheduled Cron Events</strong></p>'; | |
| echo '<table style="border-collapse:collapse;width:100%;">'; | |
| echo '<tr><th style="text-align:left;border-bottom:1px solid #ccc;padding:4px 8px;">Hook</th>'; | |
| echo '<th style="text-align:left;border-bottom:1px solid #ccc;padding:4px 8px;">Next Run</th>'; | |
| echo '<th style="text-align:left;border-bottom:1px solid #ccc;padding:4px 8px;">Schedule</th></tr>'; | |
| foreach ( $crons as $timestamp => $hooks ) { | |
| foreach ( $hooks as $hook => $events ) { | |
| foreach ( $events as $event ) { | |
| $next_run = human_time_diff( $timestamp, time() ); | |
| $direction = ( $timestamp > time() ) ? 'in ' . $next_run : $next_run . ' ago (overdue!)'; | |
| $schedule = isset( $event['schedule'] ) ? $event['schedule'] : 'single'; | |
| echo '<tr>'; | |
| echo '<td style="padding:4px 8px;font-family:monospace;">' . esc_html( $hook ) . '</td>'; | |
| echo '<td style="padding:4px 8px;">' . esc_html( $direction ) . '</td>'; | |
| echo '<td style="padding:4px 8px;">' . esc_html( $schedule ) . '</td>'; | |
| echo '</tr>'; | |
| } | |
| } | |
| } | |
| echo '</table></div>'; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # WP-CLI cron management cheatsheet | |
| # Run all commands from your WordPress root directory | |
| # or pass --path=/var/www/html to each command. | |
| # ─── List all scheduled events ───────────────────────────────────────────── | |
| wp cron event list | |
| # ─── Run all due events right now ────────────────────────────────────────── | |
| wp cron event run --due-now | |
| # ─── Run a specific hook ─────────────────────────────────────────────────── | |
| wp cron event run myplugin_hourly_event | |
| # ─── Schedule a one-time event (epoch timestamp) ─────────────────────────── | |
| wp cron event schedule myplugin_hourly_event 1735689600 | |
| # ─── Delete a specific event ─────────────────────────────────────────────── | |
| wp cron event delete myplugin_hourly_event | |
| # ─── Test whether WP-Cron is functioning correctly ───────────────────────── | |
| wp cron test | |
| # ─── List cron schedules (built-in + custom intervals) ───────────────────── | |
| wp cron schedule list |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment