The five crontab time fields — minute, hour, day-of-month, month, day-of-week — determine when a command executes. This episode breaks down each field, the *, comma, dash, and step (/) characters, month and day names, and the OR/AND rules that most often trap beginners.

In episode 2 we saw that cron works by matching five time fields. Now it's time to fully understand that scheduling language — because most chronic errors come from here: schedules that look right but run on the wrong day, or run twice.
Cron syntax is actually simple. Once you master the five fields and the *, ,, -, / characters, you can read any crontab on any server in the world.
Each crontab line starts with five fields that determine when the command runs:
minute hour day-of-month month day-of-week command| Field | Range | Meaning |
|---|---|---|
| minute | 0-59 | Minute of the hour |
| hour | 0-23 | Hour of the day |
| day-of-month | 1-31 | Day of the month |
| month | 1-12 | Month of the year |
| day-of-week | 0-7 | Day of the week (0 & 7 = Sunday) |
The simplest example — every night at 02.30:
30 2 * * * /usr/local/bin/backup.shThe day-of-month and month fields are marked *, meaning "every day" and "every month". The day-of-week field is also *, meaning "every day of the week".
* — All Values* means "every possible value". * * * * * means every minute.
* * * * * /usr/local/bin/check.sh, — ListsA comma creates a list of values. A schedule at 07:00, 12:00, and 18:00:
0 7,12,18 * * * /usr/local/bin/report.sh- — RangesA dash creates a range. Every working hour from 09.00-17.00:
0 9-17 * * 1-5 /usr/local/bin/ping.sh/ — StepsA slash sets an interval. Every 5 minutes:
*/5 * * * * /usr/local/bin/healthcheck.shA step can be combined with a range — every 10 minutes between 9 and 11:
*/10 9-11 * * * /usr/local/bin/snapshot.shCron accepts the first three letters of month and day names, case-insensitively:
month: jan feb mar apr may jun jul aug sep oct nov dec
day: sun mon tue wed thu fri sat0 22 * * mon-fri /usr/local/bin/nightly.shThis is the part most often misunderstood. When both day-of-month and day-of-week are set to specific values (not *), cron combines them with OR, not AND:
0 0 1,15 * mon /usr/local/bin/task.shThe line above runs on the 1st and 15th of every month OR every Monday — not "the 1st/15th that fall on a Monday". This means the job can run several times in a single month. This is cron's historical behavior and you should always keep it in mind.
Warning
You almost never really want a combination of non-* day-of-month + day-of-week. If your requirement is "on the 1st and 15th of every month and only on workdays", don't use those two fields together — use 0 0 1,15 * * and let the script check the day of the week itself.
# Setiap 5 menit
*/5 * * * * /usr/local/bin/check.sh
# Pukul 02.30 setiap malam
30 2 * * * /usr/local/bin/backup.sh
# Tiap Senin pukul 07.00
0 7 * * mon /usr/local/bin/weekly-report.sh
# Tanggal 1 setiap bulan pukul 00.00
0 0 1 * * /usr/local/bin/monthly-cleanup.sh
# Setiap jam kerja (09-17) tiap menit ke-0 dan ke-30
0,30 9-17 * * 1-5 /usr/local/bin/clock.shBefore saving, verify your schedule with crontab.guru (episode 7 covers it in more depth). As a quick test, count manually: 30 2 * * * means "minute 30, hour 2, all days" — clear, right? If you're unsure about a strange combination, this tool will explain it in plain language.
Tip
Get into the habit of writing the simplest schedule that meets your needs. 0 2 * * * is better than 0 2 1-31 * *. The more complex the time fields, the greater the chance of misinterpretation — especially when day-of-month and day-of-week are involved.
Key takeaways:
minute hour day-of-month month day-of-week command.* all values, , lists, - ranges, / steps, three-letter month/day names.day-of-month and day-of-week when both are non-* combine with OR.In episode 4 we'll practice crontab management — crontab -e, crontab -l, crontab -r, crontab -u for other users, plus the structure of /etc/crontab, /etc/cron.d/, and the per-user spool /var/spool/cron/. Time to write your first real schedule!