What cron is
Cron is the time-based job scheduler built into Unix and Linux systems. A background daemon (crond) wakes up every minute, reads its configuration, and runs any command whose schedule matches the current time. The configuration lives in a crontab ("cron table"), which you edit with crontab -e and list with crontab -l. Each non-comment line in a crontab defines one job, and each job line has the same shape: five time-and-date fields, then the command to run.
minute hour day-of-month month day-of-week command. Read left to right, smallest unit of time first.A complete line looks like this:
30 2 * * * /usr/local/bin/backup.sh
That says: at minute 30 of hour 2, on every day of the month, every month, every day of the week — run backup.sh. In other words, 2:30 AM daily. The three asterisks are the key: an asterisk means "every value," so leaving the date fields as * lets the time fields do all the work.
The five fields
Every cron schedule is exactly five fields separated by spaces, always in this order with these allowed values:
| Field | Allowed values |
|---|---|
| Minute | 0–59 |
| Hour | 0–23 |
| Day of month | 1–31 |
| Month | 1–12 |
| Day of week | 0–6 (Sunday = 0) |
After the fifth field comes the command — everything to the end of the line is treated as the shell command to execute. Many implementations also accept names in the last two fields (jan–dec and sun–sat), and some treat 7 as Sunday too, but the numeric form above works everywhere.
The special characters
Each field can hold more than a single number. Four characters do the heavy lifting:
*— every value in the field.*in the hour field means every hour.,— a list of specific values.0,30in the minute field means at :00 and :30.-— an inclusive range.1-5in the day-of-week field means Monday through Friday./— a step interval.*/15in the minute field means every 15 minutes (0, 15, 30, 45).
These combine freely. 0-30/10 in the minute field means "every 10 minutes from 0 to 30" — that is, at :00, :10, :20 and :30. The step character is read as "every Nth value across the range to its left," so */15 is shorthand for "every 15th minute across the whole 0–59 range."
Common schedules to copy
Most real-world jobs are variations on a handful of patterns. Here are the ones you will reach for most often:
| Schedule | Cron expression |
|---|---|
| Every minute | * * * * * |
| Every hour, on the hour | 0 * * * * |
| Every day at 2:30 AM | 30 2 * * * |
| Every Monday at 9:00 AM | 0 9 * * 1 |
| First of every month, midnight | 0 0 1 * * |
| Weekdays at 9:00 AM | 0 9 * * 1-5 |
| Every 15 minutes | */15 * * * * |
Notice the pattern: to fire at a single moment each day you pin the minute and hour and leave the rest as *. To narrow it to certain days you set the day-of-week field — 1 for Monday, 1-5 for the working week. To repeat within the day you put a step in the minute or hour field instead of a fixed number.
The day-of-month vs day-of-week gotcha
Here is the trap that catches nearly everyone. When you restrict both the day-of-month field and the day-of-week field (neither is *), standard cron does not require both to match. It runs the job whenever either one matches — the two fields are combined with a logical OR, not AND.
So 0 0 13 * 5 does not mean "midnight on Friday the 13th." It means "midnight on the 13th of every month, and midnight on every Friday." If you genuinely need Friday-the-13th behaviour, leave one day field as * and test the other inside the command, for example with a shell condition on date. When only one of the two day fields is restricted, there is no ambiguity and it behaves the way you would expect.
Shortcuts and portability
Many cron daemons accept named special strings in place of the five fields. The common ones are @yearly (same as 0 0 1 1 *), @monthly, @weekly, @daily (also written @midnight), and @hourly. There is also @reboot, which runs the command once when the cron daemon starts up rather than on a clock schedule — handy for kicking off a long-running process after a boot.
Treat these as conveniences, not guarantees. The shortcuts come from Vixie-style cron and are absent from some minimal clones. More importantly, the finer points of steps, ranges, and timezones differ between implementations. Classic Linux cron runs in the server's local timezone and honours / and - in every field, whereas managed cloud schedulers (and tools that borrow cron syntax) may interpret UTC by default, add a sixth seconds field, or reject syntax that Vixie cron accepts. Whenever you move a schedule between a server crontab and a cloud scheduler, re-read its documentation and verify the next few run times before relying on it.
The takeaway
Cron syntax is small and almost entirely positional: five fields in a fixed order, four special characters, and one OR-trap to remember. Decode any line by reading the fields left to right — minute, hour, day, month, weekday — and substitute the special characters as "every," "list," "range," and "step." Build new schedules by pinning the units you care about and leaving the rest as *. If you are working with raw timestamps alongside your schedules, the epoch converter and 24-hour time converter pair naturally with cron's 24-hour clock.
Frequently asked questions
- What are the five fields in a cron schedule?
- In order, they are minute (0–59), hour (0–23), day of month (1–31), month (1–12), and day of week (0–6, where Sunday is 0). After those five fields comes the command to run. A reliable way to remember the order is the phrase minute, hour, day, month, weekday.
- What does an asterisk mean in cron?
- An asterisk (*) means every valid value for that field. So * in the minute field means every minute, and * in the month field means every month. The expression * * * * * therefore runs the command once every minute of every hour of every day.
- Why did my job run more often than expected with both day fields set?
- When both the day-of-month and day-of-week fields are restricted (neither is *), most cron implementations OR them together rather than AND them. The job runs if either condition matches, so 0 0 13 * 5 runs on the 13th of the month AND on every Friday, not only on Friday the 13th. To require both, restrict one field and add a check inside the command.
- Are special strings like @daily and @reboot portable?
- Shortcuts such as @daily, @hourly, and @reboot are supported by most Unix cron daemons like Vixie cron, but they are not part of every implementation. Cloud schedulers and minimal cron clones may not understand them, and the exact behaviour of step, range, and timezone handling also varies, so test against your specific runtime.
Behaviour of edge cases varies between cron implementations. When in doubt, check your system's man 5 crontab and verify the next scheduled runs before relying on a job.