At first glance, running cron through a WordPress plugin looks easy. Install UpdraftPlus, set backups to daily at 2 AM, done. The plugin adds automation and convenience, no argument there. But the problem underneath every cron task in WordPress is the same: WP-Cron fires on page loads. No visitor, no trigger. On a site getting 40 hits a day, mostly during business hours, that 2 AM backup has nobody to start it.
We keep coming back to this point across our WordPress guides because it really is that important. Plugins are just a wrapper around WordPress cron. The underlying mechanism stays the same, and so do its limits. UpdraftPlus won't complete a backup on time no matter how well you configure it, if wp-cron never fires. MailPoet won't send your campaign. WooCommerce won't process subscription renewals. The plugin works fine. The trigger doesn't.
WP-Cron doesn't fail loudly. It fails by doing nothing.
Below is a plugin-by-plugin breakdown of what breaks, what URLs or commands to set up, and what interval each one actually needs. If you've already disabled wp-cron and set up an external trigger (adding define('DISABLE_WP_CRON', true); to wp-config.php and pointing a real cron at wp-cron.php), you're covered for most of these. But a few plugins (WP All Import, BackWPup) have their own dedicated cron endpoints that bypass wp-cron.php entirely.
UpdraftPlus: backups that actually run on schedule
UpdraftPlus is the most installed backup plugin on WordPress (3M+ active installs), and it depends entirely on WP-Cron for scheduling. The plugin registers updraft_backup and updraft_backup_increments hooks, then waits for wp-cron to fire them. On low-traffic sites, that wait can stretch to hours or days.
UpdraftPlus itself warns about this in their docs: "using WP-CRON in the default configuration is unreliable and can result in corrupt backups." Corrupt, not just late, because a backup that starts at an unexpected time can collide with another process or run during peak load. Not a theoretical risk.
Setup
UpdraftPlus doesn't have its own cron URL. It piggybacks on the standard wp-cron trigger:
# System crontab
*/15 * * * * /usr/bin/curl -s "https://yoursite.com/wp-cron.php?doing_wp_cron" > /dev/null 2>&1
# Or WP-CLI (no HTTP request, faster)
*/15 * * * * cd /var/www/html && /usr/local/bin/wp cron event run --due-now > /dev/null 2>&1
Match the trigger frequency to your backup schedule. Daily backups need wp-cron triggered at least every 2-4 hours. Hourly backups need it every 5-15 minutes. If you're using an external cron service for WordPress, set the interval there.
WP All Import: the plugin with its own cron URLs
WP All Import is different from most plugins. It doesn't use wp-cron.php at all. Instead, it generates two unique URLs per import job, both going through wp-load.php:
# 1. Trigger URL -- starts the import
https://yoursite.com/wp-load.php?import_key=YOUR_SECRET&import_id=3&action=trigger
# 2. Processing URL -- continues chunked import
https://yoursite.com/wp-load.php?import_key=YOUR_SECRET&import_id=3&action=processing
You need both. The trigger URL kicks off the import. The processing URL handles the actual data in chunks (because PHP has execution time limits). Find your secret key at All Import > Settings, and the import ID at All Import > Manage Imports.
Recommended intervals
Set the trigger URL to match your desired import frequency: every 4 hours for a product feed, daily for a CSV sync, whatever fits. Set the processing URL to every 2 minutes. It needs to run repeatedly until the import finishes, and each run processes one chunk before timing out.
I've seen shops lose a full day of product updates because they set up the trigger but forgot the processing URL. The import starts, processes 50 products, hits the PHP timeout, and sits there waiting for the next processing call that never comes.
WooCommerce and Action Scheduler
WooCommerce (5M+ active installs) doesn't use WP-Cron directly for most things. It runs on Action Scheduler, a job queue system that stores pending actions as custom post types. But Action Scheduler itself is triggered by WP-Cron, through the action_scheduler_run_schedule hook. So the dependency chain is still there.
What Action Scheduler processes: order confirmation emails, webhook deliveries, product stock updates, and (if you're running WooCommerce Subscriptions) recurring payment renewals. Late subscription renewals mean direct revenue loss. An email that should go out when a customer places an order at 2 AM sits in the queue until someone visits the site at 8 AM.
Setup
# Every minute is ideal for WooCommerce
* * * * * /usr/bin/curl -s "https://yoursite.com/wp-cron.php?doing_wp_cron" > /dev/null 2>&1
# Or with WP-CLI (runs Action Scheduler directly)
* * * * * cd /var/www/html && /usr/local/bin/wp action-scheduler run > /dev/null 2>&1
The WP-CLI approach is better here because it skips the HTTP overhead and runs the scheduler process directly. For a deeper dive into WooCommerce specifically, see our WooCommerce external cron guide. You can check the backlog at WooCommerce > Status > Scheduled Actions. If you see "past-due" actions piling up, your trigger isn't firing often enough.
BackWPup: per-job trigger URLs
BackWPup gives you two scheduling options: "with WordPress cron" (same wp-cron dependency as everyone else) or "Triggered by link." The second option generates a unique secure URL for each backup job. Hit that URL and the backup starts immediately, no wp-cron involved.
# BackWPup's own trigger (find this in the job's Schedule settings)
*/30 * * * * /usr/bin/curl -s "https://yoursite.com/?backwpup_run=UNIQUE_KEY" > /dev/null 2>&1
Worth using the dedicated URL instead of relying on wp-cron. Fewer moving parts.
MailPoet: three sending modes, only one works well
MailPoet offers three options in Settings > Advanced for its newsletter sending queue:
1. Visitors trigger (default): sends batches when someone visits the site. Same problem as wp-cron on low-traffic sites. A campaign to 5,000 subscribers can take days to finish if you're getting 100 visits/day.
2. WordPress cron: better, but still depends on wp-cron firing on schedule.
3. Server-side cron: runs the sending daemon via PHP CLI. This is the reliable option.
For option 3, MailPoet shows you the exact command in its settings panel. It looks something like:
# MailPoet server-side cron (exact path from your Settings > Advanced)
*/2 * * * * /usr/bin/php /var/www/html/wp-content/plugins/mailpoet/mailpoet-cron.php /var/www/html > /dev/null 2>&1
Don't try to call MailPoet's cron via HTTP. Their endpoint returns 404 for external requests. You need the PHP CLI command. Every 2 minutes is their recommended interval for the sending queue.
FluentCRM: email campaigns and automation
FluentCRM schedules email sending every minute, email processing every 5 minutes, and various housekeeping tasks hourly. All through WP-Cron. For a marketing automation tool, this dependency on page-load triggering is a real problem. A welcome email sequence that fires at unpredictable intervals makes a terrible first impression.
No dedicated cron URL here. Standard wp-cron trigger, but fire it frequently:
* * * * * /usr/bin/curl -s "https://yoursite.com/wp-cron.php?doing_wp_cron" > /dev/null 2>&1
FluentCRM has a health checker at FluentCRM > Settings that shows whether scheduled jobs are running on time. Check it after setting up external cron. Green means it's working.
Yoast SEO: background indexation you don't see
Yoast runs background indexation that processes about 15 posts every 15 minutes via wp-cron. On a site with 10,000+ posts, this indexation takes days to complete even when cron fires reliably. When wp-cron is unreliable, Yoast's internal tables go stale: new content doesn't appear in the sitemap, SEO analysis data lags behind edits, and the internal linking suggestions stop updating.
There's no separate configuration needed. Once you have wp-cron.php triggered externally every 15 minutes, Yoast's indexation runs as expected. But if you've ever published a post and wondered why it didn't show up in your XML sitemap for hours, this was probably why.
WP Rocket: cache preloading needs a steady beat
WP Rocket's preload feature crawls your entire site to warm the cache. It processes 45 URLs per batch, with 60-second gaps between batches. Each batch is a wp-cron event. On a site with 500 pages, that's about 12 batches, which takes around 12 minutes when cron fires reliably and over an hour when it doesn't.
Database cleanup (clearing expired transients, post revisions, spam comments) also runs on WP-Cron. Without reliable triggering, these maintenance tasks pile up and the database bloats.
# Every 5 minutes covers both preloading and cleanup
*/5 * * * * /usr/bin/curl -s "https://yoursite.com/wp-cron.php?doing_wp_cron" > /dev/null 2>&1
Gravity Forms, MemberPress, and the rest
Not every plugin needs its own section. Here's what else depends on wp-cron and what breaks when it's unreliable:
Gravity Forms runs a backup notification processor every 5 minutes. If you use date-based notifications (send an email 3 days after form submission), those fire via wp-cron. Missed triggers mean missed follow-ups.
Membership plugins feel this acutely. MemberPress and Restrict Content Pro handle subscription expirations, renewal reminders, and drip content unlocking through wp-cron. A membership that should expire at midnight might not actually revoke access until the next morning when someone visits. Drip content that should unlock on Day 7 might not unlock until Day 8. LearnDash has the same problem with drip-fed lessons: if a student should get access to Lesson 3 on Tuesday, wp-cron needs to fire on Tuesday to make that happen.
Even WordPress core itself relies on wp-cron for scheduled post publishing, trash cleanup, and update checks. The "Missed schedule" error on posts is the most visible symptom of unreliable wp-cron. It's been frustrating WordPress users for over a decade.
One trigger vs. dedicated plugin URLs
Most plugins on this list work fine with a single external trigger to wp-cron.php?doing_wp_cron. Set it to every minute or every 5 minutes, and all schedule-dependent plugins pick up their events on time. That covers UpdraftPlus, WooCommerce, FluentCRM, Yoast, WP Rocket, Gravity Forms, MemberPress, LearnDash, and core WordPress.
Two exceptions need their own cron entries:
WP All Import uses its own trigger + processing URLs through wp-load.php. The standard trigger won't start your imports.
MailPoet (in server-side mode) requires a PHP CLI command, not an HTTP request.
BackWPup works with either approach, but their dedicated per-job URL is more reliable than going through wp-cron.
For sites running on shared hosting where you can't add system cron entries, WatchCron's Cloud Cron for WordPress handles the external triggering without server access. You get a monitoring layer on top: if the trigger fails or your site goes down, you get an alert before the next scheduled backup or email batch is missed. The plugins don't tell you when their cron events are being skipped. Silence is the whole problem with wp-cron.
One more thing: diagnosing wp-cron issues is straightforward once you know the symptoms. But fixing it once doesn't mean it stays fixed. Plugin updates, hosting migrations, caching plugin conflicts (some aggressively cache wp-cron.php responses). Any of these can break your cron trigger again without warning. That's why monitoring the trigger matters as much as setting it up.