Cron syntax hasn’t changed in decades, but it still trips people up constantly — five fields, no labels, and a single misplaced comma silently turns “every weekday at 9am” into “every day, every 9 minutes.” Most cron tools will validate your syntax, but they won’t tell you what it actually means or when it will actually run next. That gap is where scheduling bugs live.
Quick answer
A cron expression has 5 fields, in order: minute hour day-of-month month day-of-week. Each field accepts * (any value), a single number, a list (1,15), a range (1-5), or a step (*/15). If both day-of-month and day-of-week are restricted (not *), cron treats them as an OR, not an AND — this is the single most common source of confusion.
Cron Expression Builder & Explainer
| Field | Raw Value | Plain English |
|---|---|---|
| Minute | ||
| Hour | ||
| Day of Month | ||
| Month | ||
| Day of Week |
Next 5 Run Times
Cron Syntax Cheat Sheet
| Field | Allowed Values | Notes |
|---|---|---|
| Minute | 0–59 | |
| Hour | 0–23 | 0 = midnight, 23 = 11 PM |
| Day of Month | 1–31 | |
| Month | 1–12 or JAN–DEC | Names are case-insensitive |
| Day of Week | 0–7 or SUN–SAT | Both 0 and 7 mean Sunday |
| Symbol | Meaning | Example |
|---|---|---|
* | Any value | * * * * * — every minute |
, | A list of values | 1,15 — the 1st and 15th |
- | A range of values | 1-5 — Monday through Friday |
/ | Step values | */15 — every 15 units |
Common Mistakes That Break Cron Jobs
1. Assuming day-of-month and day-of-week are ANDed together
If you set both fields to something other than *, cron runs the job when either condition is true, not only when both are true. 0 0 15 * 1 doesn’t mean “the 15th, if it’s a Monday” — it means “the 15th of every month, AND every Monday.” If you need a genuine AND condition, leave one of the two fields as * and add the extra logic inside your script instead.
2. Forgetting the job runs in the server’s time zone, not yours
A job scheduled for 0 9 * * * on a server set to UTC fires at 9:00 AM UTC — which might be 4 AM or 5 PM where you actually are. Always check the system time zone (timedatectl on most Linux systems) before assuming a schedule matches your local clock.
3. Off-by-one on day-of-week numbering
Cron’s day-of-week is 0-indexed starting at Sunday: 0 or 7 = Sunday, 1 = Monday, … 6 = Saturday. It’s easy to assume Monday is 0, especially coming from languages that index differently.
4. Using a step on a non-zero start and expecting it to align to the hour
*/15 in the minute field always starts counting from 0, giving you 0, 15, 30, 45. A step like 5/15 starts at 5, giving you 5, 20, 35, 50 instead — not the top-of-hour alignment people usually expect.
5. Missing that some systems support 6-field cron (with seconds)
Standard Unix cron uses exactly 5 fields. Some tools and libraries (many Java schedulers, some CI platforms) add a 6th leading “seconds” field. If your expression has 6 parts and the platform’s docs don’t mention seconds, you likely have a formatting mismatch, not a syntax error.
Troubleshooting Checklist
- Paste the expression into the tool above and check the plain-English summary matches what you actually intended.
- Confirm the next 5 run times line up with your expectations — this catches AND/OR day-field confusion immediately.
- Check the server or platform’s time zone, not your local one.
- Confirm the field count (5 vs. 6-with-seconds) matches what your specific scheduler expects.
- Check your crontab has a trailing newline — some cron implementations silently ignore the last line without one.
- Verify the script or command itself runs cleanly when executed manually, outside of cron’s minimal environment (cron often runs with a stripped-down
PATHand no shell profile loaded).
FAQ
What does */5 mean in a cron expression?
It means “every 5 units of that field, starting from 0.” In the minute field, */5 produces 0, 5, 10, 15, and so on through 55.
How do I run a job every weekday?
Use 1-5 or MON-FRI in the day-of-week field, and leave day-of-month as * — for example, 0 9 * * 1-5 runs at 9 AM every weekday.
Why did my job run on a day I didn’t expect?
This is almost always the day-of-month/day-of-week OR behavior — if both fields are restricted, the job fires whenever either one matches, not only when both match.
Does cron account for daylight saving time?
Behavior varies by cron implementation, and this is a common source of jobs silently skipping or double-firing around DST transitions. If exact timing matters, check your specific cron daemon’s documentation or use UTC to sidestep the issue entirely.
What’s the difference between crontab -e and a system cron file?
crontab -e edits a per-user crontab and does not require a username field. System-wide files like /etc/crontab or files in /etc/cron.d/ require an extra username field between the schedule and the command.

