Queuety
Features

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 processed by the Queuety worker, which provides reliable execution independent of site traffic.

Enabling the replacement

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

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 functionFilter hookedBehavior
wp_schedule_event()pre_schedule_eventCreates a Queuety schedule with the same interval
wp_unschedule_event()pre_unschedule_eventRemoves the corresponding Queuety schedule
wp_get_scheduled_event()pre_get_scheduled_eventReturns 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:

  1. Resolves the schedule name (e.g. hourly) to an interval in seconds using wp_get_schedules()
  2. Creates a Queuety schedule with the handler name __queuety_cron_{hook}
  3. Stores the original WordPress hook name and arguments in the schedule payload

When the Queuety worker processes the scheduled job, it calls do_action() with the original hook name and arguments. All callbacks registered for that WordPress cron hook are executed as normal.

Interval resolution

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

Schedule nameInterval
hourly3,600 seconds
twicedaily43,200 seconds
daily86,400 seconds
weekly604,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:

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 WP-Cron replacement is useful when:

  • Your site has low traffic. WP-Cron relies on page visits to trigger scheduled events. If your site gets few visitors, cron events can be delayed significantly.
  • You need reliable timing. Queuety's worker runs continuously and checks schedules on a fixed interval, independent of site traffic.
  • You are already running the Queuety worker. If you have a worker process running, routing cron events through it means one fewer system to manage.
  • You want centralized observability. Cron events processed through Queuety appear in the job logs and metrics alongside your other queue jobs.

Limitations

  • Requires an active Queuety worker. If the worker is not running, cron events will not be processed.
  • Single-fire events are not intercepted. Only recurring schedules (those with a schedule property) are routed through Queuety.
  • DISABLE_WP_CRON is permanent for the request. Once replace_wp_cron() is called, DISABLE_WP_CRON is defined as true for the remainder of the PHP process. Calling restore_wp_cron() removes the filter hooks but does not un-define the constant.
  • WordPress must be loaded. The bridge hooks into WordPress filters and calls do_action(). It does not work in standalone (non-WordPress) mode.

Example: full setup

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

After this, any plugin that calls wp_schedule_event() will have its events routed through Queuety automatically. The original hook callbacks continue to work without modification.

On this page