# Find and Remove Orphaned Cron Events

> Adds Tools > Orphaned Cron Events, listing scheduled tasks that no active plugin or theme handles any more (often left by uninstalled plugins) and removing them after you confirm.

- Type: PHP
- Runs: Admin only
- Category: [Performance](https://wpide.com/library/category/performance/)
- Tags: cron, cleanup, scheduling
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/perf-orphan-cron-cleanup/

## Code

```php
add_action( 'admin_menu', function () {
    add_management_page( 'Orphaned Cron Events', 'Orphaned Cron Events', 'manage_options', 'wpide-orphan-cron', function () {
        $find = function () {
            $orphans = array();
            foreach ( (array) _get_cron_array() as $time => $hooks ) {
                foreach ( (array) $hooks as $hook => $events ) {
                    if ( ! has_action( $hook ) ) {
                        $orphans[ $hook ] = ( isset( $orphans[ $hook ] ) ? $orphans[ $hook ] : 0 ) + count( $events );
                    }
                }
            }
            return $orphans;
        };

        if ( isset( $_POST['wpide_cron_hooks'] ) && check_admin_referer( 'wpide_orphan_cron' ) && current_user_can( 'manage_options' ) ) {
            $orphans = $find();
            $removed = 0;
            foreach ( array_map( 'sanitize_text_field', (array) wp_unslash( $_POST['wpide_cron_hooks'] ) ) as $hook ) {
                if ( isset( $orphans[ $hook ] ) ) {
                    $removed += (int) wp_unschedule_hook( $hook );
                }
            }
            printf( '<div class="notice notice-success"><p>%s</p></div>', esc_html( sprintf( 'Removed %d scheduled event(s).', $removed ) ) );
        }

        $orphans = $find();
        echo '<div class="wrap"><h1>Orphaned Cron Events</h1>';
        if ( ! $orphans ) {
            echo '<p>Every scheduled event has a handler. Nothing to clean up.</p></div>';
            return;
        }
        echo '<form method="post" onsubmit="return confirm(\'Remove the selected scheduled events?\');">';
        wp_nonce_field( 'wpide_orphan_cron' );
        echo '<table class="widefat striped" style="max-width:640px"><thead><tr><td class="check-column"></td><th>Hook</th><th>Scheduled events</th></tr></thead><tbody>';
        foreach ( $orphans as $hook => $count ) {
            printf( '<tr><th class="check-column"><input type="checkbox" name="wpide_cron_hooks[]" value="%1$s" aria-label="%2$s" checked></th><td><code>%3$s</code></td><td>%4$d</td></tr>', esc_attr( $hook ), esc_attr( 'Select ' . $hook ), esc_html( $hook ), (int) $count );
        }
        echo '</tbody></table>';
        submit_button( 'Remove selected events' );
        echo '</form></div>';
    } );
} );
```

## Notes

A task is shown when nothing is hooked to it on admin pages; a few plugins only hook their tasks during cron, so check the hook names before deleting.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Find and Remove Orphaned Cron Events" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
