macOS 14+ · Menu bar app
What runs on this Mac, and when?
Every cron job and every scheduled launchd agent in one list, with the next run written in plain English, drawn on a timeline, and a reason when a job never fires.
macOS 14 or later. 14-day unrestricted trial. No account. One license, three Macs, a year of updates.
$ brew tap suresk/tap
$ brew install --cask suresk/tap/cronmon
Both schedulers on one screen: your crontab, and the launch agents Homebrew, Docker, your updaters and you installed.
Where launchd's run count and last exit code come from. No password, no background daemon, no root.
CronMon scans when you open it, when a launchd directory changes, and when you ask. It never polls.
The schedule
The next 24 hours, on one strip
30 4 * * 1-5 becomes "At 04:30 on weekdays". A StartCalendarInterval with three of its five keys missing becomes "Every day at 03:35". Next up lists the five closest runs and how long until each; the strip below puts a dot on every run in the window, over an axis marked in hours.
Look ahead 6 hours, 24 hours, or 7 days. Search by name or command, move with the arrow keys, press Return to open a job. Copy Summary puts the whole list on the clipboard as plain text.
History, honestly
What actually ran
launchd tells us runs and exit codes; for cron we watch the process while CronMon runs. So a launch agent shows the run count, last start and last exit code that launchd itself recorded, whether or not CronMon was open. A cron job shows the runs CronMon saw, dated from when it started watching, and labelled as such.
There is nothing better to read: cron writes no entries to the unified log at any level. What CronMon can add is the job's last output, taken from the mailbox cron delivers it to.
The diagnosis
Why the job did not run
Every job is checked against the things that quietly break scheduled work on a Mac, and each finding carries its fix in the same sentence: a command that is not on cron's PATH, with the directory it is actually in; an executable that is not there at all; a job that touches Desktop, Documents or Downloads before cron has Full Disk Access; output being mailed where nobody will read it; a schedule that matches no date in the next five years; a StartInterval too short for launchd to honour.
Run Now runs a cron job with the environment cron would have given it and shows you what it printed. Disable comments the line out, Enable puts it back, and both write a backup of your crontab first.
Why cron jobs fail on macOS
The PATH is not yours
A cron job runs with PATH=/usr/bin:/bin. Not your shell's PATH, not /opt/homebrew/bin, not /usr/local/bin. The line that works when you paste it into Terminal fails at 4am with "command not found", and the message goes somewhere you never look.
Full Disk Access
macOS keeps cron out of Desktop, Documents, Downloads and removable volumes until you allow it: System Settings › Privacy & Security › Full Disk Access, add /usr/sbin/cron. Until then a backup script reading ~/Documents gets "Operation not permitted" every night.
Output goes to mail
Anything a cron job prints is mailed to the local mailbox at /var/mail/<user>. No Mail.app account reads it, no notification fires, and nothing in the unified log records the run either. The job looks like it never happened.
Pricing
CronMon
$19 one-time
- cron and launchd on one timeline, plain-English schedules, diagnostics
- Run now, enable and disable, Copy Summary
- Three Macs per license, deactivate yourself
- Twelve months of updates included; $9/year to keep them coming
- 14-day refund, no questions
Checkout is handled by Polar, our merchant of record. Your key arrives by email.
Try it first
14 days, everything unlocked, no account, no sign-up. When the trial ends every job, schedule, diagnosis and history stays visible; running a job now and switching one on or off need a license.
DownloadQuestions
I can already do this with crontab -l and launchctl list. Why pay?
Those two commands are genuinely most of the answer, and if they are enough for you, keep them. What they do not give you: crontab -l prints five-field expressions, not the times they mean, and launchctl list prints every loaded job whether it is scheduled or not, so finding the scheduled ones means opening property lists by hand. Neither puts the two schedulers in one order by when they next run. CronMon adds four things on top: next runs for both, in English and on a timeline; the history that exists — launchd's run count and last exit code, and the cron runs CronMon watched; a check of each job for the PATH, Full Disk Access and mail-output traps, with the fix; and Disable, which comments out one crontab line and keeps a backup, instead of you editing the file. $19 once, and a 14-day trial to find out.
cron or launchd — which should I use?
launchd, for anything new. It is what macOS actually schedules with, it runs jobs that were missed while the Mac slept, and it records run counts and exit codes you can read back. cron still works and is far quicker to write, which is why most Macs have both. CronMon shows them together because the answer to "what runs at 4am" is usually spread across the two. There is a guide comparing them.
Does it need root?
No. CronMon 0.1.0 asks for no password and installs nothing privileged: your crontab, the launchd property lists it can read, and launchctl print are all available to you as a normal user. Root's crontab and the system daemons are the part a normal user cannot reach, and reaching them needs a privileged helper — that is what 1.1 adds; until then those jobs are shown read-only or not at all.
Why not the App Store?
The sandbox forbids what CronMon does: read your crontab through /usr/bin/crontab, read launchd property lists across the system, and run launchctl. Direct download, notarized by Apple, is the only way this app can exist. Homebrew works too.
Does it edit my crontab?
Only when you press Disable or Enable, and only one line: Disable puts #CRONMON-DISABLED in front of it, Enable takes that marker off. Everything else in the file, your comments and environment lines included, comes back byte for byte. A copy of the crontab is written to ~/Library/Application Support/CronMon/crontab-backups/ before the change, and the result is read back and checked.
Can it write cron expressions for me, or convert cron to launchd?
Not in 0.1.0. CronMon reads and explains schedules; it does not edit expressions and does not convert between the two schedulers. Both are on the list.
Why does a cron job show fewer runs than it has had?
Because nothing on macOS records them. launchd keeps a run count and the last exit code for its own jobs; cron keeps nothing and writes no entries to the unified log. CronMon watches the cron process while CronMon itself is running and reports only what it saw, dated from when it started watching. Turn on Launch CronMon at login and it sees the runs that happen before you open it.
Does it phone home?
Two calls: license validation and update checks. No telemetry, no accounts. Your crontab and your launchd property lists are read on your Mac and go nowhere. See Privacy.
Can I use one license on my work and home Macs?
Yes. Three activations per license; free one from the customer portal whenever you need the seat back.