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

Last Updated on April 11, 2025 EDT by Jordan

Content Error or Suggest an Edit

Notice a grammatical error or technical inaccuracy? Let us know; we will give you credit!

What is the WP-Cron

WP-Cron is WordPress’s built-in system for managing scheduled tasks. It allows WordPress core, themes, and plugins (like WooCommerce) to perform time-based operations such as publishing scheduled posts, checking for updates, sending email notifications, or clearing expired transients.

Unlike traditional cron systems that run on a fixed schedule via the server, WP-Cron is triggered by site traffic. When a user visits the site, WordPress checks if any scheduled tasks are due to run. If so, it attempts to execute them during that same request cycle.

PHP is Not Asynchronous

WP-Cron is designed to run automatically when a user visits your site. While WordPress attempts to trigger it in a non-blocking way (since version 2.1), PHP itself is not asynchronous. This means that under certain conditions, WP-Cron can still block or delay a visitor’s request.

Even though WordPress uses a non-blocking HTTP request to execute wp-cron.php, issues like DNS resolution delays, SSL negotiation failures, firewalls (such as Cloudflare or security plugins), and fallback to slower transports like fsockopen (rare) can prevent the cron call from returning quickly. When this happens, it can slow down the page load for the visitor who happened to trigger the cron — or even cause timeouts.

WP-Cron Can Be a Bottleneck

Because WP-Cron relies on user visits to trigger scheduled tasks, it can become a performance liability — particularly on busy or underpowered servers. When tasks are executed during a user’s request, they may consume additional resources or introduce latency, even when WordPress attempts to run them non-blocking.

To avoid this, a widely recommended approach is to disable WP-Cron’s automatic triggering and replace it with a real cron job at the server level. This allows scheduled tasks to run independently of user activity, leading to more consistent performance and fewer unexpected slowdowns.

WP-Cron Timing: Finding the Right Balance

When switching to a server-level cron job, the frequency at which you run wp-cron.php depends on your site’s specific needs.

For most WordPress sites, running wp-cron.php every 5 to 15 minutes is sufficient. However, if your site relies heavily on scheduled tasks — such as processing WooCommerce orders, membership renewals, or time-sensitive content — you may want to schedule it as often as once per minute.

Site Type Recommended Frequency

  • Low-traffic blogs or brochure sites Every 15–30 minutes
  • Medium-traffic sites or basic eCommerce Every 5–10 minutes
  • High-traffic sites or task-heavy (e.g. WooCommerce, LMS) Every 1–5 minutes

Keep in mind that running wp-cron.php too frequently can create unnecessary load, especially if there are no pending tasks. Monitor performance and adjust based on actual cron activity.

Step 1 – 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');

Step 2 – Choose a Method for Running WordPress Cron

Method #1 – WordPress Cron using wget/curl

Most 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 Solution to wget or curl Issues?

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. Increasing 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

The Benefits of wget or curl Method?

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

Method #3 – Execute cron.php using PHP CLI

Another method is to use PHP via the CLI and execute cron.php as shown below

*/5 * * * * /usr/local/lsws/lsphp74/bin/lsphp /home/managingwp.io/public_html/cron.php > /dev/null

There may be reasons for this, but I don’t personally utilize this method.

Additional WordPress Linux Cron Options

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

Logging Cron Run Times

If you have a heavily trafficked site, you might need to log the run times of your WordPress cron. You can do so with the following code.

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

The above code will time the run of your WordPress cron and each task, and provide the following output.

 0.65s user 0.14s system 93% cpu 0.850 total

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.

Better Uptime Heartbeat Monitoring

If you have Better Uptime (Affiliate Link) you can monitor your cronjob run using the following command.

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

They also provide an example using a script which is actually better for catching errors.

Cron and heartbeat monitor | Better Stack Documentation
betterstack.com

Cronitor Monitoring

Another popular cron monitoring service is Cronitor which will monitor and alert you if your cronjob takes too long to run, fails to run and etc.

Effectively giving you a total run time and CPU usage utilized. This can help for troubleshooting.

Monitoring WordPress Cron using a Must-Use Plugin

The following article provides instructions on how to use a must-use plugin and Betteruptime’s Heartbeat feature.

Setting Up Cron Jobs on Kinsta Hosting for WordPress Sites
Setup server-level cron jobs with wp-cli for Kinsta hosting to ensure site performance & compliance with Better Uptime heartbeat monitoring. Easily modify intervals and ensure scheduled tasks are completed as expected with a few simple tweaks.
www.sprucely.net

ManagingWP WordPress Linux Cron Shell Shim

I’ve created this script that you can use as a shim between the Linux cron and wp-cli and do the following.

  • Utilizes wp-cli cron command to run all cron events.
  • Automatically detects webroot (htdocs/public_html) if one level below WordPress Root.
  • Checks if WordPress root exists and is a WordPress installation.
  • Logging to a file or syslog with a tag and domain name of the WordPress instance using wp-cli options
  • Log includes output and errors, date and time, how long the cron ran for and the CPU time.
  • Can specify a heartbeat URL for monitoring (BetterUptime/Uptimerobot)
  • Post command that can be run afterwards which can be another script or curl to post to a webhook.
wp-shelltools/cron-shim.sh at main · managingwp/wp-shelltools · GitHub
GridPane CLI made in Bash. Contribute to managingwp/wp-shelltools development by creating an account on GitHub.
github.com

WordPress Cron Tools and Other Information

Sacling WP-Cron

Automattic’s cron-control-runner written in Go

GitHub – Automattic/cron-control-runner: Go-based runner for Cron Control
Go-based runner for Cron Control. Contribute to Automattic/cron-control-runner development by creating an account on GitHub.
github.com

Automattics’s Cron-Control Plugin (parallel, with custom event storage for high-volume cron)

GitHub – Automattic/Cron-Control: A fresh take on running WordPress’s cron system, allowing parallel processing
A fresh take on running WordPress’s cron system, allowing parallel processing – Automattic/Cron-Control
github.com

Monitoring WordPress Cron via Heartbeat Checks

https://www.sprucely.net/knowledge-base/monitoring-wordpress-cron-via-heartbeat-checks

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.

Resources

    Changelog

    • 04-11-2025 – Updated introduction to wp-cron and added more details about the lack of PHP not being asynchronous. Updated formatting of article and corrected mistakes.
    • 04-21-2023 – Added link to Github repository containing cron-shim.sh
    • 04-13-2023 – Corrected some typo’s and incorrect code. Added Resources section. Added cron-shim script.
    • 08-25-2022 – Added Cronitor and Logging Cron Run Times sections.
    • 09-21-2022 – Taken out of draft.
    0 Shares:

    You May Also Like