You’ve reached a draft 🤷♂️ and unfortunately, it’s a work in progress.
Table of Contents
- What is the WP-Cron
- First Step, Disable the WordPress WP-Cron From Running on Page Visits
- Method #1 – WordPress Cron using wget/curl
- Method 2# – WordPress Cron using WP-CLI (Preferred Method)
- Logging WordPress Cron
- Monitoring your 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.
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. */”.
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.
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.
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.
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.
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
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.
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
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
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>
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.