Cron explained
Cron runs commands on a schedule, if you can read its five fields. Here is the syntax, the step/range tricks, the OR gotcha, and the schedules you'll actually write.
What cron is
Cron is the time-based job scheduler on Unix-like systems. It reads a crontab (cron table), a list of entries that each pair a five-field time pattern with a command. Every minute, cron checks which patterns match the current time and runs their commands. It is how servers send nightly reports, rotate logs, take backups, and trigger any recurring task, and the same five-field syntax shows up well beyond classic cron, including CI schedulers.
The five fields
A crontab line is five time fields followed by the command. Read left to right: minute, hour, day-of-month, month, day-of-week.
# +-------------- minute (0 - 59)
# | +------------ hour (0 - 23)
# | | +---------- day of month (1 - 31)
# | | | +-------- month (1 - 12)
# | | | | +------ day of week (0 - 6, Sun = 0)
# | | | | |
* * * * * command-to-run | Field | Range | Notes |
|---|---|---|
| Minute | 0 - 59 | |
| Hour | 0 - 23 | 24-hour clock |
| Day of month | 1 - 31 | |
| Month | 1 - 12 | Names (JAN) often allowed |
| Day of week | 0 - 6 | Sunday = 0 (7 also Sunday on many systems) |
Ranges, lists & steps
*any value (“every”).1-5a range (1 through 5).1,15,30a list of specific values.*/15a step, every 15th across the field (0, 15, 30, 45).
Real schedules
0 9 * * 1-5 # 9:00 AM, Monday through Friday
*/15 * * * * # every 15 minutes
0 0 1 * * # midnight on the 1st of every month
30 2 * * 0 # 2:30 AM every Sunday
0 */6 * * * # every 6 hours (00:00, 06:00, 12:00, 18:00)
@daily # shorthand for 0 0 * * * Rather build and read these visually? The cron generator turns plain English into a crontab expression and back, with the next run times.
The day-of-month vs day-of-week gotcha
The single most surprising cron rule: when both the day-of-month and the day-of-week fields are
restricted (neither is *), cron runs the job when either matches, not both. So
0 0 13 * 5 fires on the 13th of the month or on any Friday, never “Friday the
13th only.” If you need an AND, restrict just one field and test the other inside your command.
Why jobs fail to run
- Wrong schedule. Test the expression before trusting it (the generator shows next runs).
- Bare environment. Cron runs with a minimal
PATH, use absolute paths to binaries. - Silent output. Redirect stdout/stderr to a log so you can see what happened.
- Timezone surprises. Confirm whether it is local time or UTC, prefer UTC for predictability.
FAQ
What is cron?
Cron is the time-based job scheduler on Unix-like systems. It reads a 'crontab' (cron table) of entries, each pairing a five-field time pattern with a command, and runs each command whenever the current time matches its pattern.
What do the five fields mean?
In order: minute, hour, day-of-month, month, and day-of-week. Each can be a number, a list (1,15), a range (1-5), a step (*/15), or * for 'any'. The command to run follows the five fields.
How do day-of-month and day-of-week interact?
This is the classic gotcha: when BOTH day-of-month and day-of-week are restricted (neither is *), cron runs the job when EITHER matches, not both. So '0 0 13 * 5' runs on the 13th OR on any Friday, not only Friday the 13th.
What does */15 mean?
A step value: 'every 15th'. In the minute field, */15 fires at minutes 0, 15, 30, and 45. */6 in the hour field means every 6 hours. The * is the range, the /15 is the interval across it.
What are @daily, @hourly, @reboot?
Named shortcuts many cron implementations accept instead of five fields: @hourly (0 * * * *), @daily / @midnight (0 0 * * *), @weekly, @monthly, @yearly, and @reboot (run once at startup). Handy, but not universal, plain five-field syntax is the most portable.
What timezone does cron use?
Traditionally the server's local timezone, which is a frequent source of 'it ran an hour off' bugs, especially around daylight-saving changes. Many modern schedulers (and CI systems like GitHub Actions) run in UTC. Always confirm which, and prefer UTC for anything that must be predictable.
Why isn't my cron job running?
Common causes: the schedule is wrong (test it first), the command needs an absolute path (cron runs with a minimal environment and a bare PATH), output/errors go unseen (redirect to a log to debug), or the crontab line lacks a trailing newline. Run the command by hand first to rule the command itself out.
Related concepts
Cron generator · Shell scripting · HTTP explained · all references.
Reading a crontab line at a glance is a rite of passage KB Cafe documented in the server-admin era. This is the modern restoration, the five fields, the step tricks, and the OR gotcha that has burned every engineer at least once, paired with a generator so you never have to count asterisks again.