Profile WordPress Cron Jobs With VVV

I recently found that I needed to Profile WordPress Cron to figure out the best way to improve the processing time on background file imports.

In an effort to better handle on large location imports in Store Locator Plus, I re-architected the Power add on to split the process into 3 steps.   The first step uploads the file to the server; something that is typically fairly fast and only ties up a user’s web browser for a few minutes as most people are no longer on dial-up.   The second step, the reason WordPress Cron is now in play, is to fire off a background process via WP Cron to then parse the CSV file.     This second process is the one I want to profile.

Luckily I am using a typical VVV setup as part of my development environment.   It has Webgrind, a PHP cache grind file reporting tool, already enabled “out of the box”.   I only need to run the debug_on command from the Virtualbox command line and then add &XDEBUG_PROFILE to the end of any URL request to get a view into what functions are called and how much CPU time they are eating up.

Things get tricky if you want to profile WordPress Cron processes though.    Since they are fired off from WordPress automatically, how do you add a GET variable?

Turns out there is a WordPress hook called curing the WordPress ‘init’ hook processing.    ‘cron_request’ allows you to change the arguments passed to WordPress Cron jobs.   This is the “secret sauce” needed to add the profiler argument and trigger the automatic creation of a Cachegrind file.

I put this in my plugin invocation class that fires up  before ‘init’ is called.

 public static function init() {
        static $instance = false;
        if ( ! $instance ) {
            load_plugin_textdomain( 'slp-power' , false , SLPPOWER_REL_DIR . '/languages/' );
            $instance = new SLPPower( array(
                                          'version'         => SLP_POWER_VERSION ,
                                          'min_slp_version' => SLP_POWER_MIN_SLP ,

                                          'name'        => __( 'Power' , 'slp-power' ) ,
                                          'option_name' => 'slp-power' ,
                                          'file'        => SLP_POWER_FILE ,

                                          'activation_class_name'    => 'SLPPower_Activation' ,
                                          'admin_class_name'         => 'SLP_Power_Admin' ,
                                          'ajax_class_name'          => 'SLP_Power_AJAX' ,
                                          'userinterface_class_name' => 'SLPPower_UI' ,
                                      ) );

        if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
            add_filter( 'cron_request', array( $instance, 'modify_cron_request' ) );

        return $instance;

     * Add profiler to cron requests.
     * @param $request
     * @return mixed
    public function modify_cron_request( $request ) {
        $request['url'] .= '&XDEBUG_PROFILE';
        return $request;

If I have WP_DEBUG_LOG enabled it will not automatically create the cache grind profiles.    Sweet!

Example WordPress Cron Cachegrind Output
Example WordPress Cron Cachegrind Output

Now to improve the background list processing!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.