Skip to content

WP-Cron Replacement

Queuety can replace the built-in WordPress cron system. When enabled, calls to wp_schedule_event() are intercepted and routed through Queuety's scheduler instead of the default WP-Cron mechanism. Events are meant to be processed by the Queuety worker, which provides execution independent of site traffic.

Current limitation: the bridge creates the Queuety schedules, but the worker has no handler for the __queuety_cron_{hook} jobs they produce, so the original WordPress callbacks never run. Each job fails, is retried with backoff, and is eventually buried (#9). Do not enable the bridge on a site whose cron events must run until that is fixed.

Enabling the replacement

Call Queuety::replace_wp_cron() early in your plugin or theme initialization:

PHP
use Queuety\Queuety;

Queuety::replace_wp_cron();

This is typically called in your plugin's main file or in a plugins_loaded hook. It must be called while WordPress is loaded (the plugin must be active).

What it intercepts

The cron bridge hooks into three WordPress filters:

WordPress function Filter hooked Behavior
wp_schedule_event() pre_schedule_event Creates a Queuety schedule with the same interval
wp_unschedule_event() pre_unschedule_event Removes the corresponding Queuety schedule
wp_get_scheduled_event() pre_get_scheduled_event Returns schedule data from Queuety

Only recurring events (those with a schedule property like hourly, twicedaily, daily) are intercepted. Single-fire events scheduled with wp_schedule_single_event() are not intercepted.

How events are mapped

When a plugin calls wp_schedule_event(), Queuety resolves the schedule name through wp_get_schedules(), creates a Queuety schedule with the handler name __queuety_cron_{hook}, and stores the original WordPress hook name and arguments in the schedule payload.

The intended behaviour is that the Queuety worker processing that scheduled job calls do_action() with the original hook name and arguments, so the existing WordPress callbacks run with Queuety driving the timing. CronBridge::process_cron_event() implements that call, but nothing invokes it yet (see the limitation above). Schedules are also only evaluated by a long-running wp queuety work process, about once a minute (see Scheduling).

Interval resolution

The bridge resolves schedule names through wp_get_schedules() first, then falls back to built-in defaults:

Schedule name Interval
hourly 3,600 seconds
twicedaily 43,200 seconds
daily 86,400 seconds
weekly 604,800 seconds

Custom schedule intervals registered via the cron_schedules filter are supported as long as wp_get_schedules() returns them.

Restoring WP-Cron

To revert to the default WordPress cron system:

PHP
Queuety::restore_wp_cron();

This removes the filter hooks and allows WordPress to handle cron events through its built-in mechanism again. Note that DISABLE_WP_CRON is defined as true when the bridge is installed and cannot be un-defined at runtime, so you may need to remove that constant from wp-config.php or restart the process.

When to use it

The replacement is most useful when your site has low traffic, when you need more reliable timing than WP-Cron can provide, or when you are already running Queuety workers and want cron execution to live in the same operational system. It also helps when centralized observability matters, because cron events then show up in the same logs and metrics as your other queue work.

Limitations

There are a few important constraints. An active Queuety worker is required, otherwise the scheduled events will never run. Only recurring schedules are intercepted; single-fire events created with wp_schedule_single_event() still stay outside the bridge. replace_wp_cron() also defines DISABLE_WP_CRON for the rest of the current PHP process, so restore_wp_cron() removes the hooks but cannot un-define the constant. Finally, the bridge only works when WordPress is loaded, because it depends on WordPress filters and do_action().

Example: full setup

PHP
use Queuety\Queuety;

// In your plugin's main file.
add_action( 'plugins_loaded', function () {
    Queuety::replace_wp_cron();
} );

There is no need to call Queuety::init() here: the active Queuety plugin builds its connection from the WordPress database credentials and initializes itself on plugins_loaded. replace_wp_cron() only installs the filters, so it does not depend on that having happened first.

After this, recurring events that plugins register with wp_schedule_event() are stored as Queuety schedules. Until #9 is fixed, their callbacks do not run.