Replacing WordPress WP Cron with Linux cronjob (URL and wp-cli Method)

Draft Warning

You’ve reached a draft 🤷‍♂️ and unfortunately, it’s a work in progress.

What is the WP-Cron

The WordPress WP-Cron is used to run scheduled tasks within WordPress core, as well as plugins such as WooCommerce.

The WordPress WP-Cron will run on each page visit by a visitor, this can result in the WP-Cron running multiple times on busy sites and con under up slowing down

The WordPress cron will run automatically when a visitor visits your site. This can cause an unnecessary load on your server or slow down the single request and result in a slower load time of your site.

A popular option is to disable the automatic WordPress cron, and replace it with a manual cron. Below are two methods to achieve this.

First Step, Disable the WordPress WP-Cron From Running on Page Visits

This is required, and simple edit of your wp-config.php. Locate the following line below, and change it from false to true. You may not have it in your wp-config.php; simply add it above the line “/* That’s all, stop editing! Happy publishing. */”.

define('DISABLE_WP_CRON', 'true');

Method #1 – WordPress Cron using wget/curl

The majority of articles talking about using the Linux crontab to run the WP-Cron will reference using wget or curl. There are a couple of issues with this that I’ve highlighted below.

Issue #1 – Network, DNS and SSL Issues

The issue with wget/curl is that you’re adding networking overhead, potentially going through multiple firewalls, WAF’s like Cloudflare, and Wordfence. You’re also dependent on local DNS resolution and the domain name resolving correctly. DNS can have issues, it’s not invincible. The same is true of SSL, if your SSL expires then, of course, there are bigger issues.

If there is an issue with any of these, your WP-Cron won’t run.

Issue #2 – Long Running Request and Timeouts

Networking has timeouts, and as such if a request is taking too long and reaches the timeout the request is closed or terminated. There are timeouts everywhere, including your WAF and your own webserver. Again with longer running processes, you’ll see issues and potentially a cron that never finishes completely at times which can cause issues for time-sensitive actions on larger sites. Granted the cron will re-run from where it last finished, but if the connection was terminated during a function that doesn’t complete, then the task is incomplete. If the task was a daily task, it would not run again until the next day.

Issue #3 – Potential for a DDoS attack.

This doesn’t really seem to be something anyone talks about. Providing a web endpoint that will cause an increase in resources is an opportunity for a DDoS attack. You can eat up connections, or increase the host’s resources.

The wget/curl Solution?

There isn’t a solution to the timeouts, you can increase your timeouts on PHP and your webserver but they’re still a limit and not infinite until the request is completed. The increasing of timeouts can also potentially leave you susceptible to a DDoS attack, using up all your connections. One thing is sure, don’t use wget, use curl instead, which I’ll explain below.

Look at using wp-cli and run cron events, or you could simply send the request locally to the web server versus out to the internet and back. You can use the –header option in curl to send a request to the local web server at localhost/127.0.0.1 versus using the domain name or DNS of the site. Then block requests to wp-cron.php from anywhere but localhost/127.0.0.1 Here’s an example of block requests to wp-cron.php at Cloudflare or your WAF.

curl -L -k --header "Host: managingwp.io" https://127.0.0.1

It’s important that you use -L, as it will follow redirects. And -k is required as it will not verify the SSL certificate common name and the URL being used which will mismatch due to the certificate common name being managingwp.io and the URL being https://127.0.0.1

Benefiets of using wget/curl

There is one benefit to using wget/curl, you’ll be able to utilize opcode caching to speed up these requests. Granted on smaller sites the speed up might not be much, on larger sites it might save you 30 seconds of 100% CPU usage (PHP will use as much CPU as possible).

You do have to make sure that you configure your OPCode cache settings correctly. You’ll need to make sure all files are cached, and that requires quite a bit of memory. Which might not be possible in some instances.

Method 2# – WordPress Cron using WP-CLI (Preferred Method)

This is the preferred method since it will work if there are DNS and other network issues.

*/5 * * * * /usr/local/bin/wp --path=/var/www/managingwp.io/htdocs cron event run --due-now > /dev/null 2>&1

Logging WordPress Cron

If you want to log to a file, you can add the following; just make sure the user running the cron has access to the log file.

*/5 * * * * /usr/local/bin/wp --path=/var/www/managingwp.io/htdocs cron event run --due-now >> //var/log/wp-cli-cron.log 2>&1

Monitoring your WP-Cron

You can monitor your WP-Cron using something called a heartbeat monitor, which is something that comes with certain monitoring platforms such as Better Uptime (Affiliate Link)

*/5 * * * * /usr/local/bin/wp --path=/var/www/managingwp.io/htdocs cron event run --due-now > /dev/null 2>&1 && https://betteruptime.com/api/v1/heartbeat/<heartbeatid>

Conclusion

As mentioned above using wp-cli to run your WordPress cron is the preferred method as it will bypass DNS, SSL and timeouts from PHP and your webserver.

0 Shares:
You May Also Like