WordPress wp-cron.php Not Running on cPanel – Real Fix Without Plugins
WordPress relies on wp-cron.php to publish scheduled posts, send emails, run WooCommerce tasks, and more.
On many cPanel shared hosts it stops working, and you see things like:
- Scheduled posts missed their publish time
- WooCommerce follow-up emails never send
- Backup jobs or clean-ups never run
The problem: WordPress’ default cron only runs when someone visits your site. If traffic is low or the host blocks loopback requests, cron gets stuck.
The real solution on cPanel is to disable the built-in pseudo cron and replace it with a real server cron job. No plugin needed.
1. Check if wp-cron is actually failing
First, try hitting it manually in your browser:
https://yourdomain.com/wp-cron.php?doing_wp_cron
You will usually get a blank page or a tiny output. That’s fine.
Now check if scheduled tasks are still stuck:
- Scheduled post still shows “Missed schedule”
- WooCommerce status shows pending actions
Tools → Site Health → Info → Scheduled eventsshows overdue tasks
If things only move when you manually hit the URL, cron is not firing by itself.
2. Disable WordPress’ built-in wp-cron
We want the server to call wp-cron.php on a fixed schedule.
Before adding the real cron job, disable the automatic one so it doesn’t run on every page load.
Edit wp-config.php (in the site root) and add this line above the line that says “That’s all, stop editing! Happy publishing.”:
define( 'DISABLE_WP_CRON', true );
This stops WordPress from trying to run cron on normal page views.
3. Create a real cron job in cPanel
Now we’ll tell the server to call wp-cron.php every 5 or 10 minutes.
3.1 Open the Cron Jobs section
- Log in to cPanel
- Look for Cron Jobs under Advanced
- Scroll down to Add New Cron Job
3.2 Choose the schedule
For most sites, every 5 minutes is great:
- Common Settings: Once Per Five Minutes
This will auto-fill the Minute / Hour / Day / Month / Weekday fields.
3.3 Set the command
You have two good options: using wget/curl or using PHP CLI.
Use whichever your host allows.
Option A: wget
wget -q -O - https://yourdomain.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1
Option B: curl
curl -s https://yourdomain.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1
Option C: PHP CLI (more reliable on some hosts)
Replace /usr/local/bin/php with the correct PHP path for your account, and /home/USERNAME/public_html with your real path:
/usr/local/bin/php -q /home/USERNAME/public_html/wp-cron.php >/dev/null 2>&1
You can usually see the right PHP path in cPanel → PHP Info or ask the host’s support.
Click Add New Cron Job to save it.
4. Make sure the path and URL are correct
If you installed WordPress in a subfolder, adjust the cron command.
Examples:
- Site URL:
https://yourdomain.com/blog - Files:
/home/USERNAME/public_html/blog
wget / curl version:
curl -s https://yourdomain.com/blog/wp-cron.php?doing_wp_cron >/dev/null 2>&1
PHP CLI version:
/usr/local/bin/php -q /home/USERNAME/public_html/blog/wp-cron.php >/dev/null 2>&1
If you see “No such file or directory” in cron emails, the path is wrong. Fix the folder and save again.
5. Test if cron is now running
After saving the cron job:
- Wait 5–10 minutes
- Create a new post and schedule it a few minutes in the future
- Check if it publishes on time
Also look at:
- WooCommerce → Status → Scheduled Actions
- Any backup/cleanup tasks with a future schedule
If they now run without you manually visiting the site, the real cron is working.
6. Common problems and how to fix them
6.1 Cron emails full of output
If you do not suppress output, cPanel will email you every 5 minutes.
Make sure your command ends with:
>/dev/null 2>&1
That discards normal output and errors, keeping your inbox clean.
6.2 HTTPS / SSL issues
If your site uses HTTPS, always use the https:// URL in wget or curl.
If cron fails due to SSL verification, your host might need CA certificates updated or you can switch to the PHP CLI version which runs locally without HTTPS.
6.3 Multiple WordPress installs on the same account
Each site needs its own cron job.
Example: you have:
public_html→ main sitepublic_html/blog→ second site
Create two separate cron jobs:
curl -s https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1
curl -s https://example.com/blog/wp-cron.php?doing_wp_cron >/dev/null 2>&1
or two PHP CLI commands with their own paths.
6.4 Heavy tasks causing timeouts
If you have huge WooCommerce or membership sites, cron tasks can run long.
- Use a slightly longer interval (every 2–5 minutes instead of every minute)
- Ask your host for higher PHP max_execution_time if cron scripts time out
- Split your heavy jobs (imports, massive emails) into batches where possible
7. Optional hardening: block public access to wp-cron.php
Once cron is working, you can optionally block direct web access to wp-cron.php so only the server cron runs it.
For Apache, add this to .htaccess in your WordPress root:
<Files "wp-cron.php">
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Files>
Or only allow your server’s IP (your host can provide it).
Do this only if you are using the PHP CLI method or you know the allowed IP.
8. Quick checklist
When wp-cron.php is not running on cPanel:
- Add
define( 'DISABLE_WP_CRON', true );inwp-config.php - Create a real cron job in cPanel (every 5 minutes is fine)
- Use
curl,wget, or PHP CLI with the correct path/URL - Suppress output with
>/dev/null 2>&1 - Test scheduled posts and tasks after a few minutes
- Add one cron per WordPress install if you host multiple sites
After this, you have a proper system cron instead of WordPress’ fake one, and your scheduled tasks will run reliably without installing any extra plugins.