TL;DR
Switch from WP-Cron to real server cron when scheduled jobs must run reliably or visitor-triggered cron adds performance risk. Real cron gives predictable timing, but the jobs still need monitoring.
- WP-Cron is acceptable for small sites with normal traffic and non-critical scheduled tasks.
- Use real cron for stores, memberships, backups, imports, email queues, and low-traffic sites.
- Disable WP-Cron only after confirming the server cron command runs and logs correctly.
How WP-Cron Actually Works
WP-Cron is not a server daemon. It is a request-triggered scheduler that checks for due events when visitors hit the site. That design is simple, but it means no traffic can equal no execution. On low-traffic sites, a job scheduled for 02:00 may not run until 07:00 or later if nobody visits the site overnight.
This is acceptable for development, personal projects, or content sites where tasks are forgiving. It becomes a problem when scheduled publishing, automated emails, cleanup jobs, backups, or renewals need consistent execution windows.
Signals That You Should Switch
- Scheduled posts are published late or miss narrow launch windows.
- Email, cleanup, or sync jobs stack up after periods of low traffic.
- Plugin tasks run unpredictably after cache warmups or theme changes.
- Automation failures show up in logs but do not have a reliable trigger path.
- Business workflows depend on timing rather than eventual execution.
You do not need a huge site to justify real cron. You need a workflow that is harmed by delay. A small store with scheduled fulfillment tasks can have a stronger cron requirement than a larger brochure site.
A Simple Decision Framework
- Stay on WP-Cron: local sites, sandbox projects, and low-risk blogs with flexible timing.
- Move to real cron: production sites with backups, scheduled publishing, memberships, commerce, or critical cleanup jobs.
- Use hybrid only temporarily: during migration or testing while you validate the new schedule path.
The right question is not “is WP-Cron bad?” The right question is “what happens if this job runs late?” If the answer is “nothing serious,” you can leave it alone. If the answer is “we miss revenue, data, or a promise,” move the job to server cron.
Migration Checkpoints Before You Switch
Before disabling the internal trigger, inventory every plugin and custom task that relies on cron. Look for scheduled post publishing, newsletter sends, cache purges, backup jobs, expiration cleanup, and any custom hooks added in theme or mu-plugin code.
Then verify your server can actually run the replacement command. On most hosts that means either a cron entry that calls wp-cron.php directly or a scheduled WP-CLI command such as wp cron event run --due-now. If the host blocks cron, the migration is incomplete.
How to Debug a Broken Schedule
Use the server log analyzer to check for timeouts, permission errors, or repeated 404s on wp-cron.php. If events are queued but not completed, the issue may be a plugin conflict rather than the scheduler itself. If no requests are made at all, the trigger path is likely missing.
A good test is to schedule a low-risk event, then compare the scheduled time with the actual execution timestamp. If the delay varies wildly, the site needs a deterministic schedule source. That is the point where real cron stops being optional.
Recommended Production Path
- Disable the visitor-triggered cron in production.
- Run a fixed server cron every 5 minutes or another interval that matches the site’s workload.
- Log job execution so missed tasks are visible quickly.
- Keep the original WP-Cron path documented for rollback and troubleshooting.
This gives you predictable execution without changing how WordPress stores scheduled hooks. The underlying system stays familiar; only the trigger source becomes reliable.
Pick the trigger model before you ship the feature
If a job matters enough to monitor, it probably deserves a deterministic schedule source. That is the line between convenience and operations.
Production Use Case
Cron scheduling supports the WP-Cron tool and solves real reliability problems for low-traffic or task-heavy sites.
The post should clearly explain that WP-Cron is traffic-triggered. The decision to switch should be based on missed events, imports, backups, queues, or scheduled publishing reliability.
- Apply the examples to a staging site first, then document the exact setting or code path you changed.
- Recheck linked tools, screenshots, commands, and code snippets whenever WordPress or server behavior changes.
- Refresh the guide when the workflow changes so the page remains useful as a standalone reference.
Frequently Asked Questions
What is the biggest sign WP-Cron is failing?
Jobs run late, miss windows during low traffic, or pile up after plugin changes and cache flushes.
Do small WordPress sites need a real cron?
If they rely on reliable publishing, email, cleanup, or backups, yes. Site size alone does not decide the architecture.
Can WP-Cron and real cron both exist?
Yes, but in production you usually disable the internal trigger and let the server cron call the scheduled runner on a fixed interval.
What should I test after switching?
Scheduled posts, email jobs, backups, cleanup tasks, and any plugin that depends on recurring execution.