Cron Monitor
See what every WordPress cron job did, get alerted when one fails or stops, and clean up duplicate and leftover events.
Solid choice
Cron Monitor is a solid plugin choice in 2026, with a few things worth checking first. Was last updated 7 days ago, and scores 64/100 on our health check.
- Actively developed — last update 7 days ago
- Tested with the latest WordPress (7.1)
- Small user base (<10 active installs)
- Very few reviews so far
How does it stack up?
Side-by-side on installs, updates, ratings & supportDaily downloads
Download spikes usually follow a new release — each site that auto-updates counts as a download.
Rankings
Where Cron Monitor stands todayWordPress.org search rankings
Live position in the plugin search, top 100| Keyword | Position |
|---|---|
| cron | >100 |
| cron job | >100 |
| cron log | >100 |
| scheduled events | >100 |
| wp cron | >100 |
About Cron Monitor
From the official readme · v2.0.0Description
WordPress runs background tasks, called cron jobs, for things like publishing scheduled posts,
sending emails and running backups. It keeps no record of them, so when one fails or stops you
never find out.
Cron Monitor keeps that record. It shows what ran, what failed and which plugin is behind each
job, and it tells you when something goes wrong.
Features
- Run history: every job that ran, how long it took and whether it worked.
- Filter and retry: narrow run history by date, failed runs or hook name, and retry a failed run in one click while its job is still scheduled.
- Catches crashes: fatal errors and timeouts are recorded too.
- Plugin owner: see which plugin or theme created each job.
- Safe cleanup: finds jobs left behind by deleted plugins and tells you which are safe to delete.
- Duplicate finder: spots jobs scheduled twice and removes the extras, with a preview first.
- Health check: a list of cron problems on your site, most important first, including jobs that got slower and jobs that start late.
- Alerts: email, Slack or Discord when a job crashes, runs late or stops running.
- Manage jobs: add, edit, run now, pause or delete any scheduled job.
- Pause a job: stop one job without turning off the plugin that owns it.
- Bulk actions: pause, resume or delete up to 200 jobs at once.
- Custom schedules: create your own intervals, like every 10 minutes.
- Fixed time of day: keep a daily job at 03:00, even when the clocks change.
- What changed: see which jobs appeared or disappeared in the last week.
- WooCommerce: logs failed Action Scheduler tasks.
- CSV export: download jobs and run history.
- Developer tools: WP-CLI commands and a REST API (see Technical details below).
Good to know
- Alerts are off until you turn them on.
- Alerts go only to the email address and webhook you set up; nothing else leaves your site. No tracking, no ads.
- Deleting the plugin removes everything it created.
Technical details
WP-CLI
wp cronmon runs: recorded runs. Filters:--hook,--status,--since,--limit. The
limit is a whole number from 1 to 1000 (default 20); anything else is an error, not rounded.wp cronmon health: the Cron Health findings. Exits non-zero when one is critical.wp cronmon orphans: every event with its safe-to-delete verdict.--verdictshows only one
verdict:active,unknown,cron-only,orphaned,pausedorexcluded. Any other value is
an error, not an empty list.
All three accept --format=json.
REST API
Both routes require manage_options. Use Application Passwords over HTTPS.
GET /wp-json/cronmon/v1/health: the Cron Health findings, acriticalcount and anok
boolean for Uptime Kuma, Zabbix, Better Stack and similar monitors.GET /wp-json/cronmon/v1/runs?status=fatal&since=-1%20hour&limit=20: recorded runs. Timestamps
are ISO 8601 UTC.
Logging from your own code
Inside a cron callback, attach a note to the current run:
do_action( 'cronmon_log', 'reindexed 412 products' );
With Cron Monitor inactive, the call does nothing.
Server cron setup
Add to wp-config.php:
define( 'DISABLE_WP_CRON', true );
Then add a system cron entry, every five minutes:
*/5 * * * * cd /path/to/wordpress && wp cron event run --due-now > /dev/null 2>&1
Or, without WP-CLI:
*/5 * * * * wget -q -O - https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1
Cron Monitor never writes to wp-config.php.
How it works
- A run is recorded when it starts, not when it finishes, so crashes and timeouts still leave a
record. - Cron Monitor attaches itself to every scheduled hook, so a hook with no callbacks now fires and
is recorded as “0 callbacks”. Nothing else changes. - Duplicates are matched on hook, arguments and schedule together. One-off events are never
removed automatically. - Late-running cron is traced to the job that held the cron lock too long, and a
WP_CRON_LOCK_TIMEOUT value is recommended.
Performance
- Front-end page views load two small PHP files and run no queries. With alerts on, one or two
queries are added unless you have a persistent object cache. - Each cron job adds two database writes, one when it starts and one when it finishes.
- Measured instrumentation cost is about 0.005 ms and 2.7 KB per cron job (PHP 8.4, one machine).
What this plugin stores
Two database tables per site:
cronmon_runs: one row per run. Hook name, an md5 hash of the arguments (never the values),
timing, memory, query count, outcome, and the first error message (up to 2,000 characters).
If your own code callscronmon_log, its notes are stored on the run too: up to 50 notes of 500
characters each, and 8,000 characters in all per run.cronmon_hooks: one row per scheduled event, with the callbacks last seen on it and who owns
them. Rows for events that never ran and have no guard or pinned time are pruned.
Options, in the WordPress options table:
cronmon_settings: your settings, including the alert email address and webhook URL.cronmon_recording_enabled: whether run history is switched on.cronmon_paused: the jobs you have paused.cronmon_schedules: your custom schedules.cronmon_blocked: the last 20 attempts the duplicate guard refused.cronmon_changelog: the jobs that appeared or disappeared recently.cronmon_alert_item_*: one row for each alert waiting to be delivered, at most 200, each dropped
after 24 hours.cronmon_alert_queueis the older single-row version of this queue and only
exists on sites upgraded from before 1.5.2.cronmon_overdue_next_check: when the stopped-running check may next run.cronmon_webhook_next_attempt: when the alert webhook may next be tried. After a webhook request
fails, it rests for 5 minutes.cronmon_db_version: the database version of the two tables.
Transients (short-lived cache entries):
cronmon_alerted_*: one per job that raised an alert, so the same job is not alerted again
within your throttle period.cronmon_overdue_seen: the overdue job seen by the stopped-running check.cronmon_spawn_status: the result of the wp-cron.php check, cached for an hour.cronmon_critical_findings: the count shown in the menu badge, cached for an hour.cronmon_event_form_<user id>: the values you typed into the Add event form if it was refused,
kept for 2 minutes so the form can be filled in again.cronmon_request_error_<user id>: an error message to show you once, kept for 1 minute.cronmon_install_retry: set for 5 minutes after a failed table install, so the install is not retried on every request.
By default, successful runs are kept for 7 days and failures for 14, capped at 50,000 rows. You
can change all three under Tools → Cron Monitor → Settings. No IP addresses,
user names or visitor data are stored. The only user information is your own user ID in the names
of the last two transients, and the alert email address you enter yourself.
Everything above is removed on uninstall. The one exception is a cronmon_alerted_* transient on a
site with a persistent object cache, which cannot be found by name and expires on its own within
your throttle period.
No third-party libraries are bundled and nothing is minified.
External services
This plugin contacts no third-party service of its own. No analytics, no update checker. It makes
at most two kinds of outbound request, both under your control:
- Alert webhook (optional, off by default): sent to the URL you enter, typically Slack or
Discord. A request is made only when alerts and the webhook are switched on and a job crashes,
runs late or stops running, or when you press Send test alert. It is sent at the end of the
page request, and if it fails it is retried later, no sooner than 5 minutes after, and dropped
after 24 hours. The JSON body contains these keys:event(fatal, drift or overdue),hook
(the job’s hook name),args_hash(an md5 hash, never the arguments),site(your site’s home
URL),url(a link to Run History in your WordPress admin),started_at,duration(null for drift and overdue alerts), and
message,textandcontent(the same one-sentence summary, which includes your site’s home
URL; Slack readstextand Discord readscontent). Depending on the event it also haserror
(the truncated error message of a crash),count(how many jobs are overdue),late_by,gap
andexpected(seconds). Your site’s home URL is therefore sent to the service you chose. Terms
and privacy policies: Slack
terms and
privacy policy; Discord
terms and privacy policy. - Loopback check: the Cron Health screen, Site Health test and REST health route can ask your
ownwp-cron.phpwhether it answers. This goes to your ownsite_url(). It never runs during
cron or WP-CLI, is cached for an hour, and is skipped where something else manages cron
(Cavalcade, Cron Control,DISABLE_WP_CRON,ALTERNATE_WP_CRON).
Alert emails are sent through wp_mail() to the address you enter, using your site’s own mail
setup.
Installation
- Install the plugin from Plugins → Add New, or upload it to
/wp-content/plugins/mcron-monitor/. - Activate it.
- Go to Tools → Cron Monitor.
Duplicates and the health check work straight away. Run history fills in as your jobs run.
Frequently asked questions
Where do I see my cron jobs?
Go to Tools → Cron Monitor. Scheduled Events lists every job. Run History shows what has actually run.
Which plugin created this cron job?
Check the Owner column. “Not observed yet” means the job has not run since you installed Cron Monitor. Check back after it runs.
Is this cron job safe to delete?
Cron Monitor watches each job as it runs and tells you. “0 callbacks observed across 14 runs” is safe to delete. “Callbacks observed during cron” is not. If it has not seen the job run yet, it makes no recommendation.
Why is my cron job running twice?
It is almost always scheduled twice. The Events screen flags duplicates and shows exactly what it would remove before removing anything.
Why is WP-Cron not running?
Open the Cron Health screen. It checks the usual causes and tells you what to fix. The most common one is a low-traffic site: WP-Cron only runs when someone visits. The fix is a real server cron job, and the Health screen gives you the lines to copy.
Will it tell me when a cron job stops running?
Yes. It checks from normal page visits and alerts you when a job is overdue twice in a row, fifteen minutes apart. A site that gets no visits at all cannot check itself, so use the REST health route with an external monitor for that.
Can I get alerts by email?
Yes. Go to Tools → Cron Monitor → Settings and enter an email address, a Slack or Discord webhook, or both. The Send test alert button checks that they work.
Does it slow my site down?
No. On normal page views it does almost nothing. It only does real work while cron jobs run.
Does it work with other cron plugins?
Yes. It only watches and reports. It does not take over WordPress cron.
Can it run PHP code on a schedule?
No, and it never will. Running stored code is a security risk.
Does it work with WooCommerce?
Yes. If Action Scheduler is present, failed tasks are logged. WooCommerce is not required.
Does it support multisite?
Yes. Each site has its own history and settings. There is no network-wide dashboard.
What happens to my custom schedules if I deactivate or delete the plugin?
Move events off custom schedules before deactivating or deleting the plugin. The schedules vanish with the plugin and those events stop recurring after their next run.
Changelog
Fixes a fatal error on PHP 8 for events with named cron arguments. Settings are no longer silently clamped; invalid values are refused with a message. Adds validation to REST and WP-CLI input. Orphan verdict counters restart when a hook's callbacks change.
2.0.0
Features
* Added: Run History filters by date range (“From” and “To”, in site time), shows failed runs alone with “Failed only”, and searches by hook name.
* Added: bulk Pause, Resume and Delete on the Events screen, up to 200 events per submit; events no longer scheduled are skipped and counted in the notice.
* Added: a “Retry” link on failed Run History rows while the event is still scheduled; it runs the event like “Run now”.
* Added: Cron Health warns when a hook’s median run time in the last 24 hours is 3 times its median in the 7 days before, or more.
* Added: Cron Health warns when hooks typically start late: a median of more than 5 minutes after they were due, or 30 minutes with DISABLE_WP_CRON set.
* Added: suggested privacy policy text under Settings → Privacy, describing what Run History stores and what alert emails and the alert webhook send.
Fixes
* Fixed: events with named argument keys, for example {"post_id":5}, no longer cause a fatal error on PHP 8 in the run recorder.
* Fixed: the event form names the spring daylight-saving gap, and an edited event keeps its own time in the repeated autumn hour.
* Fixed: a failed test alert shows its own error message instead of “Failed to save settings.”
* Fixed: a refused event edit keeps the posted recurrence when it equals the event’s live schedule.
* Fixed: events with named and numeric argument keys that PHP 8 repacks are recorded.
* Fixed: the run recorder keeps a paused hook’s callback set, reports the innermost Action Scheduler exception, resets the memory peak per action on PHP 8.2 and later, and keeps the memory peak of the enclosing cron run.
* Fixed: the starvation finding shows the count of starved events beyond the recorder’s row cap as a readable sentence.
* Fixed: plugins symlinked into the plugins folder are named as the owner of their events.
* Fixed: error messages and run notes are cut at a UTF-8 character boundary, stored run notes are size-capped, and hook names over 191 bytes keep their duplicate flag and first-seen badge; only the stored state row uses the shortened form.
* Fixed: a saved webhook URL that no longer validates no longer blocks other Settings from saving.
* Fixed: a delivered test alert ends the webhook’s 5-minute rest.
* Fixed: Schedules left over from older versions that Cron Monitor skips are now listed on the Schedules screen so you can delete them, and a schedule it cannot read gets a label instead of an error.
* Fixed: a failed event edit whose original could not be restored returns to the Events list.
* Fixed: two “Run now” clicks from WP Crontrol, 15 minutes apart, no longer raise a false “overdue and has not run” alert.
* Fixed: an alert email address such as first%41last@example.com is no longer silently changed on save; an address that would be altered is refused.
* Fixed: a webhook URL over 2,048 characters is refused with a message that names the length, and the saved URL is kept.
* Fixed: a bulk Pause or Resume that changes no event now says “Nothing changed” instead of showing no notice.
* Fixed: no “Retry” link on a failed run for a hook the cronmon_excluded_hooks filter excludes.
* Changed: an event’s orphan verdict counters restart when its hook’s callback set changes, so a deactivated plugin’s event can become orphaned.
* Changed: stored schedules with a digits-only name or an interval outside 60 seconds to 366 days are skipped (they stay listed on the Schedules screen so you can delete them), and hook rows that never ran and hold no pin or guard are pruned.
Performance
* Changed: the Run History table gets indexes on duration, memory, queries and hook, so those sorts no longer scan the table. They are added on fresh installs and on reactivation only; the database version is not bumped.
* Changed: the Run History row count comes from the status counts, so a page render runs one aggregate scan.
* Changed: after an alert webhook request fails, the webhook rests for 5 minutes (cronmon_webhook_next_attempt option), so a dead endpoint no longer slows page views.
* Changed: the run recorder runs the excluded-hooks filter once per registration, and the hook state reads load only the columns they use.
Security and validation
* Changed: Settings fields that are not valid (retention numbers, throttle hours, webhook URL, email address) are refused with a message naming the field, not clamped or blanked.
* Changed: a custom schedule interval must be 60 seconds to 366 days, its display name at most 100 characters, and a name of only digits is refused.
* Changed: the REST hook and since arguments, wp cronmon runs --limit (1 to 1000) and wp cronmon orphans --verdict are validated; anything else is an error.
* Changed: event keys read from requests are validated before use, and saving an event the edit form shows read-only is refused.
* Fixed: the Cron Health scheduler commands single-quote the path and URL, and % in a path or URL is escaped in the crontab lines.
* Fixed: in CSV exports, a formula character after a semicolon or tab inside a cell is neutralised.
* Changed: a webhook URL without http:// or https:// is refused, not repaired, and an Action Scheduler mode that is not offered is refused, not replaced by the default.
Accessibility and i18n
* Changed: every counted sentence uses a plural form, and the Settings number boxes sit inside one translatable sentence each.
Documentation
* The External services and What this plugin stores sections list every request, option and transient, and the screenshot captions match the screenshots.
1.5.7
- Changed: runs on PHP 7.4 and later (was 8.1).
- Fixed: events, lanes and owners that tie on time, count or duration now list in the same order on every PHP version.
1.5.6
- Added: screenshots of every screen on the plugin page.
- Added: an up-to-date translation template (
languages/mcron-monitor.pot).
1.5.5
- Security: event references from the screens’ links and forms are strictly validated the moment
they are read, and an edit of an event that no longer exists is refused before anything is
stored. - Security: event references in forms are printed with WordPress’s own escaping functions.
1.5.4
- Fixed: events whose hook name contains unusual characters (angle brackets, percent-encoding,
doubled spaces) can now be run, edited, paused, pinned and deleted from the screens; bulk delete
reports any it could not match. - Fixed: the event edit form’s security token is tied to the specific event being edited.
- Fixed: a callback that raises huge numbers of PHP warnings no longer makes the run recorder use
unbounded memory. - Fixed: Run History and Cron Health links keep hook names containing &, + and # intact.
- Fixed: the Run History date filter rejects impossible dates.
- Fixed: the hourly pruner is rescheduled if an earlier attempt to schedule it failed.
- Fixed: on a new install, two requests recording the schedule change log at once can no longer
overwrite each other’s first snapshot.
1.5.3
- Changed: every database query is now fully prepared, and form and argument input is sanitized
field by field, as required by the wordpress.org review. - Fixed: WordPress 6.5 no longer hits an undefined function when the database upgrade runs.
- Fixed: activating or upgrading the plugin no longer rewrites every column of its tables.
- Fixed: an alert for a fatal cron run is sent in the same request, not on a later page load.
- Fixed: a failed table install is no longer recorded as a finished upgrade; it is retried.
- Changed: one-off events are no longer offered for duplicate removal.
- Fixed: pinning a duplicate occurrence moves the one selected, not its earliest sibling.
- Changed: duplicate removal goes through wp_unschedule_event() in batches of at most 100, so
unschedule filters and concurrent cron changes are respected. - Fixed: alerts queued by concurrent requests are no longer lost or delivered twice.
- Fixed: when a cron callback runs a different cron hook, what happens after it returns is
recorded against the right run. - Fixed: {} is refused as event arguments; they must be a JSON list.
- Fixed: two requests updating the new and disappeared events list at once no longer erase each
other’s changes. - Fixed: hooks whose names share the first 150 characters are no longer merged into one.
- Fixed: turning recording on or off no longer undoes a settings save made at the same moment.
Screenshots
For developers
Is this your plugin? Show off the numbers.
Add a live badge to your site, docs or GitHub README. It updates on its own — no account needed.
Best Cron Monitor alternatives
All cron plugins →FAQ
Cron Monitor: quick answers
Straight answers, pulled from live WordPress.org data.
Live data from WordPress.org · checked Oct 21, 2026
Is Cron Monitor free?
Yes. Cron Monitor is free to download and use from the official WordPress.org plugin directory.
Is Cron Monitor safe to use in 2026?
Cron Monitor is a solid plugin choice in 2026, with a few things worth checking first. Was last updated 7 days ago, and scores 64/100 on our health check.
How many websites use Cron Monitor?
Cron Monitor is active on <10 WordPress websites and has been downloaded 210 times since it launched in September 2026. It was downloaded 217 times in the last 30 days.
Does Cron Monitor work with WordPress 7.1?
Yes. The developer has tested Cron Monitor up to WordPress 7.1.3, the latest release. It requires WordPress 6.5 or newer.
What PHP version does Cron Monitor need?
Cron Monitor requires PHP 7.4 or higher. Most hosts run PHP 8.x today, so it works on any modern WordPress hosting.
When was Cron Monitor last updated?
The latest version, 2.0.0, was released on October 14, 2026 (7 days ago).
Who makes Cron Monitor?
Cron Monitor is developed and maintained by Mac.
What are the best alternatives to Cron Monitor?
The most popular alternatives to Cron Monitor are WP Crontrol (300K+ installs), Advanced Cron Manager (30K+ installs) and Missed Scheduled Posts Publ… (30K+ installs).
Powered by PageForge
Want thousands of pages that rank like these? Build them in an afternoon.
This directory runs on the same engine as PageForge. Turn any spreadsheet, CSV or API into thousands of fast, SEO-ready WordPress pages — with schema, internal links and AI-written copy baked in.
- CSV, Google Sheets & API data sources
- AI content, schema & internal links per page
- Works with Elementor, Gutenberg, Yoast & Rank Math
- Free on WordPress.org — no credit card