Somewhere in production right now, a cron job is running twice as often as its author intended, and nobody will notice until the invoice — or the data loss — arrives. I know because I have been that author. Cron's five-field syntax is tiny enough to memorize and treacherous enough to betray you: five little columns, one classic trap, and consequences measured in duplicate charges and 3am pages. Let us make sure your next schedule does exactly what you think it does.
The Five Fields, Finally Memorable
Minute, hour, day-of-month, month, weekday — in that order, always. Four operators do everything: * means every value, */n means every nth, a-b spans a range, a,b lists picks. So */15 9-17 * * MON-FRI reads: every 15 minutes, 9am to 5pm, every date, every month, weekdays only. Month and weekday fields accept names (JAN–DEC, MON–SUN), which I strongly recommend — 0 9 * * MON is self-documenting in a way 0 9 * * 1 will never be at 2am.
The Trap: Day-of-Month OR Weekday
Here is the one that bites everyone exactly once. When both day-of-month and weekday are restricted, standard cron runs when either matches — not both. 0 0 1 * MON fires on the 1st of each month and every Monday, which is almost never what the author drew on the whiteboard. Reports run twice, cleanups double-delete, customers get two emails. The fix is boring: keep one of the two fields as *, or split into two explicit schedules. And always eyeball the next five run times — our Cron Explainer computes them by brute force so surprises show up before deployment, not after.
Cron FAQs
Why did my job run at midnight instead of noon?
Check hour-field confusion first: cron uses 24-hour time, so 0 12 is noon and 0 0 is midnight. Second suspect: server timezone vs your timezone — containers famously default to UTC while you think in local time.
What is the difference between * and */1?
Nothing at all — both match every value. Use whichever reads clearer to your team and move on to real problems.
Can cron run something every 90 seconds?
Not directly — minute granularity is the floor. Run every minute and gate inside the script (exit unless the minute is even), or graduate to a real scheduler for sub-minute needs.
Testing Schedules Without Waiting a Week
The cruelest property of cron is its feedback loop: misconfigure and you wait days to discover it. Shorten the loop deliberately. First, verify with next-run computation — five upcoming timestamps tell you more than staring at asterisks. Second, deploy new jobs in dry-run mode (log what would happen, change nothing) for at least two full cycles. Third, add dead-man alerting from day one: a job that notifies only on failure still fails silently when the scheduler itself dies, so monitor for the absence of expected success signals. Finally, log every run with timestamps; when the 3am page comes, the log answers "did it run?" before you finish waking up.
Paste your schedule. Read English. Sleep better.
Explain Cron Free