1

I have some scheduled events in my WordPress site. For that I use a cron job, so it has created an option in the wp_options table.

After some days, my site is getting slow. When I check my database, it has more than 2MB of data in the cron field, so I am thinking to clean it now. Will that affect my site's cron operations?

I guess it's all about entries in the table. Due to the fuzzy entries, my site is getting slow down. Here my code.

wp_schedule_event(time(), 'daily', 'kv_daily_post_expire_check');

function kv_daily_post_expire_check() {

$the_query = get_posts( 'post_type=job&post_status=publish' );  
foreach($the_query as $single_post) {
    $id=$single_post->ID;
    $ad_close_date=get_post_meta($id, 'ad_close_date', true );
    if($ad_close_date!=''){
        $today=date("Y-m-d");
        $ad_less_close_date=$ad_close_date-3;
        if($ad_close_date<$today){
            $update_post = array(
            'ID'            => $id,
            'post_status'   =>  'expired',
            'post_type' =>  'job' );
            wp_update_post($update_post);
        }   
        else if($ad_less_close_date==$today){
            $update_post = array(
            'ID'            => $id,
            'post_status'   =>  'expired',
            'post_type' =>  'job' );
            //wp_update_post($update_post); 
            kv_author_post_expiring_soon($id,3);
        }   
    } 
}
}

and here is the data which is there in my database table.

a:7:{i:1447098349;a:3:{s:16:"wp_version_check";a:1:{s:32:"40cd750bba9870f18aada2478b24840a";a:3:{s:8:"schedule";s:10:"twicedaily";s:4:"args";a:0:{}s:8:"interval";i:43200;}}s:17:"wp_update_plugins";a:1:{s:32:"40cd750bba9870f18aada2478b24840a";a:3:{s:8:"schedule";s:10:"twicedaily";s:4:"args";a:0:{}s:8:"interval";i:43200;}}s:16:"wp_update_themes";a:1:{s:32:"40cd750bba9870f18aada2478b24840a";a:3:{s:8:"schedule";s:10:"twicedaily";s:4:"args";a:0:{}s:8:"interval";i:43200;}}}i:1447099020;a:1:{s:20:"wp_maybe_auto_update";a:1:{s:32:"40cd750bba9870f18aada2478b24840a";a:3:{s:8:"schedule";s:10:"twicedaily";s:4:"args";a:0:{}s:8:"interval";i:43200;}}}i:1447141549;a:1:{s:26:"kv_daily_post_expire_check";a:1:{s:32:"40cd750bba9870f18aada2478b24840a";a:3:{s:8:"schedule";s:5:"daily";s:4:"args";a:0:{}s:8:"interval";i:86400;}}}i:1447141669;a:1:{s:26:"kv_daily_post_expire_check";a:1:{s:32:"40cd750bba9870f18aada2478b24840a";a:3:{s:8:"schedule";s:5:"daily";s:4:"args";a:0:{}s:8:"interval";i:86400;}}}i:1447141790;a:1:{s:26:"kv_daily_post_expire_check";a:1:{s:32:"40cd750bba9870f18aada2478b24840a";a:3:{s:8:"schedule";s:5:"daily";s:4:"args";a:0:{}s:8:"interval";i:86400;}}}i:1447141909;a:1:{s:26:"kv_daily_post_expire_check";a:1:{s:32:"40cd750bba9870f18aada2478b24840a";a:3:{s:8:"schedule";s:5:"daily";s:4:"args";a:0:{}s:8:"interval";i:86400;}}}s:7:"version";i:2;}
  • 1
    Please show the exact code how you add the cron job (with an edit to your question). – kaiser Nov 8 '15 at 23:18
  • As Kaiswer said, please post the actual code you are using or, at least, something we can test. At the first glance, you are running wp_schedule_event() on every page load but it should be done only on plugin activation and cleared on plugin deactivation, otherwise you add a new cron on every page load. Things like that make people talk very bad about wp-cron performance when actually the problem is in their hands. And yes, clearing the cron row in database can make crons registered by other plugins to not exist anymore if they are registered on plugin activation as recommended. – cybmeta Nov 21 '15 at 8:15
3

If you want a quick programmatic way of looping through everything you have in the cron row inside wp_options and you have access to the site's database directly (either in a local development environment or on a webhost), you can run something like this via the command line:

mysql $YOUR_DB_NAME -e "SELECT option_value FROM wp_options WHERE option_name='cron';" | php -r '$cronArray = unserialize(file_get_contents("php://stdin")); foreach ($cronArray as $timestamp => $data) { echo $timestamp." --> ".date("c",$timestamp)."\n"; print_r($data); }'

I feel that viewing this information outside of any other context can sometimes be very illustrative. The above one-liner will give you output like the following that can then be examined further:

1446749050 --> 2015-11-05T18:44:10+00:00
Array
(
    [wp_version_check] => Array
        (
            [40cd750bba9870f18aada2478b24840a] => Array
            (
                [schedule] => twicedaily
                [args] => Array
                    (
                    )

                [interval] => 43200
            )

        )

)
1446751800 --> 2015-11-05T19:30:00+00:00
Array
(
[wp_maybe_auto_update] => Array
[...]

wp-cli is also a great option for viewing and editing this type of data:

$ wp option delete cron
Success: Deleted 'cron' option.
$ wp option get cron
array (
1447092802 =>
array (
'wp_version_check' =>
array (
  '40cd750bba9870f18aada2478b24840a' =>
  array (
    'schedule' => 'twicedaily',
    'args' =>
    array (
    ),
    'interval' => 43200,
  ),
),
'wp_update_plugins' =>
[...]

The important thing to keep in mind is that the cron row is one of WordPress's autoloaded rows. This means that the data in this row has to be queried out of the database and processed by WordPress on every single page load. So you are definitely right to want to keep the size of this row as low as possible. As @mrbobbybryant mentioned, there are also plugins that let you view and edit what is in this row via WordPress directly.

When attempting to determine what should or shouldn't be a part of this data, I would recommend looking for numerous entries of one type or any other elements that seem to not belong there. Once those elements are identified, you can work back and find the code they originated from and tweak how the crons operate there.

Also, while this shouldn't be a factor if you're up to date on your WordPress version, it is worth mentioning there was a bug that could lead to greatly increased sizes of cron option rows in WordPress 4.3: #33423 - Arguments switched in wp_batch_split_terms Cron Job in 4.3.

  • Possibly your answer is almost close to my problem. is that any trouble, when i delete this cron option from my database. will it affect my cron works. ? – Kvvaradha Nov 9 '15 at 7:31
  • Deleting the current contents of the cron option entirely could very easily affect the function of your site. For instance, a scheduled post may never be published automatically if you delete the relevant cron event. However, as long as you look at the current events to verify their function first, it is often okay to remove the row entirely. At that point, any needed events should be added again by the code responsible. This may only be a temporary fix however if the site contains poorly designed code that continues to add an excessive amount of cron events. – futuernorn Nov 9 '15 at 18:14
1

When your Cron array gets stuffed with more than one task, then there's a high chance, that you either forgot to check if there's already an unfinished task in the queue, or you have the config wrong. The config array gets used to ID a task in the queue. Meaning if you for e.g. have a typo or some other difference between wp_next_schedule() checks and wp_schedule_event(), then the check will succeed and you easily end up with the task getting added over and over again. Make sure you double check that. Better just use a variable for both the hook as well as the config to not make that mistake.

add_action( 'wp_loaded', function()
{
    $hook = 'your_custom_event';

    $task = new YourCronHandler();

    // Config: An Array of arrays
    $config = [ ( include __DIR__.'/config.php' ), ];

    add_action( $hook, $task );

    // Make sure to not run during installation or if there's already a task added
    if (
        ! defined( 'WP_INSTALLING' )
        && ! wp_next_scheduled( $hook, $config )
    ) {
        wp_schedule_event(
            time(),
            'thirtymin',
            $hook,
            $config
        );
    }
} );

Then just build your handler:

class YourCronHandler
{
    public function __invoke( Array $config = [] )
    {
        // Bootstrap your process here
    }
}

The config can easily get separated to a stand-alone file. Doing so will help to make things easier readable and in case even reusable.

<?php

return [
    'foo' => 'bar',
];

Sidenote: When your cron job is running, WP automatically adds a cron lock to the database, so you don't have to care about load balancers and different servers behind it running the same task more than once. This can't be your problem, but in such cases it's better to deactivate cron in your wp-config.php and just trigger cron manually from your cron tab on a single server instead.

Intervals

To make above example complete

In case you need a different interval, it's quite easy:

add_filter( 'cron_schedules', function( Array $schedules = [] )
{
    return $schedules + [
        'thirtymin' => [
            'interval' => HOUR_IN_SECONDS / 2,
            'display'  => 'Every Thirty Minutes'
        ],
    ];
} );
  • my code is not broken, its daily scheduled one. but the thing is, it gets increase the entries in one single column. want to know the facts, whether it will affect my cron in future or not – Kvvaradha Nov 9 '15 at 7:34
  • Take a look at the first code block and the if. You are adding one ceon job per page load. – kaiser Nov 9 '15 at 8:41
0

You should check out this developer plugin. It gives you fine control when working with cron. https://wordpress.org/plugins/wp-crontrol/

I'd also rethink your cron processes. Sounds like you might need to have some post-cron cleanup built into your code. But i'm just speculating here.

  • yes, i need to cut down the serialized data automatically, is there any way to do that,? – Kvvaradha Nov 9 '15 at 7:31
  • if i delete , will it affect my further cron jobs – Kvvaradha Nov 9 '15 at 7:32
0

Thanks for all of your comments. I found solution by myself.

The reason is the action hook we have to use it like this. otherwise, the function will be called every page we load. so here is the code , that i used to solve it.

add_action( 'switch_theme', 'kv_event_scheduler' );

function kv_event_scheduler() { 
    wp_schedule_event(time(), 'daily', 'kv_daily_post_expire_check');
}

Here the function will be hooked only once, after the theme change. So it will be hooked only once. than the cron will work daily once.

and also cleaning the cron option value will affect the functionality. but you dont need to fear for it. once you change this function like the below, it will create entries automatically.

 add_action( 'after_setup_theme', 'kv_event_scheduler' );

function kv_event_scheduler() { 
    wp_schedule_event(time(), 'daily', 'kv_daily_post_expire_check');
}

once you save this refresh a page, than change the "after_setup_theme" into "switch_theme" , than your entries will be created automatically.

I hope this one help someone who stuck on the same problem. if my solution helped anyone vote it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.