Hosting Notes
WordPress Hosting

WordPress Cron vs System Cron: Why Your Scheduled Tasks Drift

WordPress's built-in WP-Cron is not a real scheduler — it only fires when a visitor loads a page. System cron runs from the operating system on a fixed clock, which is why timing-critical work like backups, WooCommerce scheduled actions, and daily digests belongs there.

On this page
  1. How WP-Cron works
  2. Where WP-Cron breaks
  3. What system cron gives you
  4. WP-Cron vs system cron compared
  5. How to switch WordPress to real cron
  6. Before you flip the switch
  7. Frequently asked questions
  8. Related reads

How WP-Cron works

Every scheduled event in WordPress (a scheduled post going live, a plugin update check, transient cleanup, WooCommerce's Action Scheduler queue) is stored in the cron option in your database as a timestamp plus a callback name. Nothing ticks in the background watching those timestamps.

Instead, page loads trigger the check. When a request comes in, WordPress asks whether any event is due. If one is, it fires a non-blocking loopback HTTP request to wp-cron.php, which runs the jobs and exits. The schedule is attached to traffic, not to time.

That design keeps WordPress portable across cheap hosts. It also means a quiet site is effectively an unscheduled site.

Where we host this site

The plan behind Hosting Notes

Same 4 GB VPS and LiteSpeed stack we benchmark in these guides.

See Hostinger plans

Where WP-Cron breaks

  • Low traffic. A staging copy, a brochure site, or a shop overnight can go hours without a check. Daily jobs drift, scheduled posts publish late, and renewal reminders miss their window.
  • High traffic. The inverse failure. Concurrent visitors all see the same due event and all spawn wp-cron.php. You get duplicated work, PHP workers tied up, and the occasional runaway loop on the cron URL.
  • Long jobs. Backups, image regeneration, or a large import can outlast the PHP request. WordPress sets a doing_wp_cron lock flag, but there's no hard guarantee the job finishes.
  • Loopback failures. If the server can't reach its own domain (basic auth in front of the site, a strict firewall, a DNS mismatch), the spawn request never lands and the job is silently dropped with no log entry.

What system cron gives you

System cron is the operating system's scheduler. You declare an entry in the crontab, and the daemon runs it whether or not a single human is browsing. It executes once, on time, under a known user, with its own output stream you can log.

The upgrade isn't ripping out WordPress's scheduler. It's driving it from a reliable clock. The event list stays in WordPress; only the trigger changes.

WP-Cron vs system cron compared

AspectWP-CronSystem cron
TriggerIncoming page loadServer clock
Low-traffic sitesJobs missed or delayedRuns on schedule
Busy sitesDuplicate spawns possibleOne run per interval
Timing accuracyBest effortTo the minute
LoggingLimitedFull, via cron output
SetupZeroOne wp-config line plus a crontab entry

How to switch WordPress to real cron

Three steps. First, stop WordPress from spawning its own runs. Add this to wp-config.php, above the "That's all, stop editing" line:

define( 'DISABLE_WP_CRON', true );

Second, add the system entry. The WP-CLI route is cleaner because it returns an exit code you can log:

*/5 * * * * cd /home/user/public_html && /usr/local/bin/wp cron event run --due-now --quiet

No WP-CLI? A plain HTTP call works:

*/5 * * * * wget -q -O - "https://example.com/wp-cron.php?doing_wp_cron=1" >/dev/null 2>&1

Third, verify. Install WP Crontrol or run wp cron event list and confirm the timestamps advance after the first window passes. If they don't, the job is failing silently. Check the cron mail or redirect stderr to a file.

Hosting choice matters here. A Hostinger VPS gives you SSH, the hPanel Cron Jobs tool, and full control over PHP binary paths. That's what you need to run WP-CLI on a real crontab instead of patching files blind. Managed WordPress plans cover the same ground if you'd rather not touch a terminal.

Before you flip the switch

  • Set the interval tighter than your most frequent job. Five minutes covers most sites; heavy WooCommerce stores often run every minute.
  • Use --due-now, not --all. Forcing every event on every pass re-runs jobs that aren't ready.
  • Confirm the cron user can read the WordPress files and that PHP is on the CLI path. A wrong path fails without noise.
  • Keep server-level backups separate from any plugin scheduler. A cron job inside WordPress can't rescue a corrupted database.

Note

Setting DISABLE_WP_CRON stops WordPress from spawning runs, but wp-cron.php stays publicly reachable. Don't block it with a firewall rule until the system entry has run successfully at least twice. Otherwise you have no fallback if the CLI path breaks.

The short version: use WP-Cron for nothing you'd notice missing, and hand anything with a deadline to the system clock. It's a one-line config change and a crontab entry, and probably the cheapest reliability upgrade on a WordPress site.

Frequently asked questions

Does disabling WP-Cron break plugins?

No. Events stay in the database exactly as before; they simply wait for your system cron job to trigger the run instead of a page visit. The only risk is forgetting to add the cron entry, which leaves the schedule frozen.

How often should system cron run wp-cron?

Every five minutes is the standard default and handles most sites. Stores running WooCommerce Action Scheduler queues, membership renewals, or subscription billing often drop to every minute for tighter timing.

Can I run system cron without setting DISABLE_WP_CRON?

You can, but traffic will still spawn extra runs alongside your scheduled ones, producing duplicate execution and wasted PHP workers. Set the constant so there's exactly one trigger.

Is wp-cron.php different from wp cron event run?

Both bootstrap WordPress and execute due events. WP-CLI avoids the HTTP round trip, returns a proper exit code, and gives you readable output, which makes failures far easier to diagnose.

Ready to get started? Check out Hostinger's plans.

Ron

Infrastructure writer & self-hosting practitioner

I run production sites and small VPS boxes for a living — WordPress, Docker, reverse proxies and the backups that save you at 2am. Everything here is written from setups I actually maintain.

Affiliate disclosure. Some links on this page are affiliate links. If you buy through them we may earn a commission at no extra cost to you. We only recommend hosts we have paid for and tested. Read the full disclosure