WP cron issues with Apache server

We see a slow memory leak in Apache that overtime causes out of memory errors. We suspect it’s a cron issue, but we’re not certain yet. Our multisite is failing with out-of-memory errors.

I was reading through some old posts on your support site and cron off-loading looks promising, but I really couldn't tell if we would need to create cron scripts for every site in the multi-site or not. This article was the most relevant: https://premium.wpmudev.org/forums/topic/how-to-switch-from-wp-cron-to-server-cron

We're running on a Oracle Linux 7 system using Apache 2.4, PHP 7.1 and mod_php.

  • Nastia

    Hello Danny Messina

    Hope you are doing well!

    Based on the error the cron job is executed successfully. 200 error means that the proccess started suscesfully:

    POST /wp-cron.php?doing_wp_cron=1521813703.7075068950653076171875 HTTP/1.1" 200

    If the system is unresponsive, means that the server resources are not enough to execute the job that cron has started processing.

    Subsites are part of a multisite, so you will need to set up only one server cron job. Although please monitor, if the site will be unresponsive again after the cron job will start, it means that the cron job has triggered a process from a plugin that uses site resources, which are not enough for the process to complete.

    Add this line in the wp-config.php file to deactivate WordPress cron, before the "/* That's all, stop editing! Happy blogging. */ line:
    define('DISABLE_WP_CRON', true);

    Log in to a cPanel, open Cron Jobs under the Advanced section and add this line:

    wget -q -O - http://yourdomain.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1

    Replace yourdomain.com with your actual domain name. This line will set up a cron job to be executed every 30 min.

    Let me know if you have any further questions!

    Kind regards,
    Nastia

  • David Thibault

    Nastia,

    Above you stated "Subsites are part of a multisite, so you will need to set up only one server cron job." Is this correct? I'm doing subdomain multisite, and a while back I discovered I had to call wp-cron.php from every site (i.e. https://basedomain.com/wp-cron.php, https://site1.basedomain.com/wp-cron.php, etc).

    I found this now because I'm tracking down what appears to be a memory leak in wp-cron.php. I disabled wp-cron with this:
    define('DISABLE_WP_CRON', true);

    Then I set up a cron script in linux to call all the /wp-cron.php urls for every subsite. Now I see that when I do that, I end up memory on one of my httpd processes creeping up to hundreds of megabytes, and /server-status shows a bunch of open connections to wp-cron, even though I have keepalive only set to 5s in Apache.

    Do you know if it's possible or adviseable to call wp-cron from filesystem instead of via HTTP request? That would avoid it hitting Apache at all.

  • Majid

    Hey David Thibault
    I hope you are doing great today :slight_smile:

    Regarding the multsite cron jobs, It's better to use a custom php file that runs cron jobs through all of the subsites. A script like this should be able to loop through all the subsites and executes the cron jobs for each one of them.

    <?php
    if (!defined('ABSPATH')) {
    	require_once(dirname( __FILE__ ) . '/wp-load.php');
    }
    global $wpdb;
    $sites = $wpdb -> get_results("SELECT <code>domain</code>, <code>path</code> FROM " . $wpdb -> blogs);
    foreach($sites as $site) {
        $url = "http://" . $site -> domain . ((!empty($site -> path)) ? $site -> path : '/') . 'wp-cron.php';
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_exec($ch);
        curl_close($ch);
    }
    ?>

    Save it as a new file in the same directory as wp-cron.php, you can name wp-cron-mu.php for example and should be called like this
    wget -q -O - http://www.basedomain.com/wp-cron-mu.php?doing_wp_cron >/dev/null 2>&1

    Now regarding running the crons without an http request, you can try running with a PHP command, in general it would be like this
    1 * * * * user php path/to/root/folder/wp-cron-mu.php >/dev/null 2>&1 >/dev/null 2>&1

    Make sure you change the "1 * * * * " to your execution frequency needed, I'd suggest using this website to generate the cron easily if you don't have that option in your cPanel
    https://crontab-generator.org/

    You will also have to change the file path as well as the user, could be the "root" user or any other user capable of running PHP.

    Check this article here for further reading about executing wp-cron using php-cli
    https://pressjitsu.com/blog/wordpress-cron-cli/

    I hope this helps :slight_smile:
    Majid

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.