Cron expressions in practice
How the five fields work, examples you can reuse, and the mistakes that fire jobs at the wrong time. Build or decode expressions with the live Cron Generator.
What a cron expression is
A cron expression is a compact schedule. The common form has five fields: minute, hour, day of month, month and day of week. A line in a crontab file adds the command after them. The expression does not run anything by itself. A cron daemon, a CI scheduler or a cloud job runner reads it once a minute and starts the job when the current time matches.
The reference for the classic syntax is the crontab(5) manual page of the cron implementation on your system. Most Linux distributions ship cronie or a Vixie cron derivative, and the rules below follow those pages unless noted.
Field order and allowed values
┌──────── minute 0-59 │ ┌────── hour 0-23 │ │ ┌──── day of month 1-31 │ │ │ ┌── month 1-12 (or jan-dec) │ │ │ │ ┌ day of week 0-7 (0 and 7 are Sunday, or sun-sat) │ │ │ │ │ * * * * *
Each field accepts the same building blocks:
*means every value from first to last.8-11is an inclusive range: hours 8, 9, 10 and 11.1,15is a list, and lists can mix ranges:0-4,8-12./nis a step.0-23/2in the hour field means every other hour, and*/15in the minute field means minutes 0, 15, 30 and 45.- Month and weekday names use the first three letters, in any case:
mon-fri,jan,jul.
Fieldkit's generator accepts exactly this five-field form, including names and Sunday as 7, and explains it in plain English with the next five run times in your local zone.
Examples you can reuse
0 9 * * 1-5: 09:00 every weekday, Monday to Friday.*/15 * * * *: every 15 minutes, on the quarter hour.0 0 1 * *: midnight on the first day of each month.15 2 * * sun: 02:15 every Sunday.0 */6 * * *: on the hour, every six hours (00:00, 06:00, 12:00, 18:00).30 4 1,15 * *: 04:30 on the 1st and the 15th.
Steps restart every cycle
A step is evaluated inside its own field, starting from the lowest value of the range. It is not "every N units since the job started". The cronie manual gives the clearest example: */23 in the hour field runs at hour 0 and hour 23 of each day, so the gap is 23 hours, then 1 hour, then 23 again. The generator shows that expression as "At 00:00, 23:00 every day". Steps that divide evenly into the field (2, 3, 4, 6, 12 for hours; 5, 10, 15, 20, 30 for minutes) give regular intervals. Other values do not.
The day-of-month and day-of-week rule
This is the rule that surprises experienced engineers. When both day fields are restricted, meaning neither is *, the job runs when either one matches. The crontab(5) page uses 30 4 1,15 * 5 as its example: 04:30 on the 1st and the 15th of each month, plus every Friday. It is not "Fridays that fall on the 1st or 15th".
Worked example: the first Monday of the month
A team wants a report at 08:00 on the first Monday of each month. The natural first attempt is 0 8 1-7 * 1: days 1 to 7, Monday. Paste it into the generator and the explanation ends with "on day-of-month 1, 2, 3, 4, 5, 6, 7 and on Monday (whichever comes first)". In November 2026 that expression fires on 11 days: every day from the 1st to the 7th, plus Mondays the 9th, 16th, 23rd and 30th. Only one of those runs, Monday the 2nd, was wanted.
Five-field cron cannot express "first Monday" on its own. The usual fix is to schedule days 1 to 7 and let the command check the weekday:
0 8 1-7 * * [ "$(date +\%u)" = 1 ] && /usr/local/bin/monthly-report
date +%u prints the weekday as 1 for Monday through 7 for Sunday, so the report only runs on the Monday inside the first week. The backslash before % is not optional. In a crontab line, an unescaped % in the command is turned into a newline, and everything after it is sent to the command as standard input. That rule breaks many date calls copied from a terminal into a crontab.
Time zones
Classic cron evaluates the schedule in the system's local time zone. Servers and containers are often set to UTC, so 0 9 * * * may mean 09:00 UTC, which is 06:00 in São Paulo. Many schedulers let you choose:
- cronie supports a
CRON_TZvariable at the top of a crontab to set the zone for the entries in it. - Kubernetes CronJobs take a
.spec.timeZonefield such asEtc/UTC. Without it, the schedule follows the time zone of the kube-controller-manager. Kubernetes rejectsCRON_TZorTZinside the schedule string. - GitHub Actions schedules run in UTC by default, and the documentation now describes an optional
timezonekey with an IANA zone name next tocron.
The generator lists next runs in your browser's zone and shows that zone in the readout, so compare it with the zone of the machine that will actually run the job.
Daylight saving time
In zones with DST, one night a year skips an hour and another repeats one. The general crontab(5) text warns that times inside the skipped hour never match and times in the repeated hour can match twice. Cronie's cron(8) adds special handling for clock changes of less than three hours: jobs scheduled in a skipped interval run right after the change, and jobs are not run twice when the clock goes back. GitHub Actions moves a schedule in a skipped hour to the next valid time. Behavior depends on the runner, so the safest choice for important jobs is to avoid the 01:00 to 03:00 window in DST zones, or to schedule in UTC.
Platform differences
- Field count. Some schedulers, such as Quartz in the Java world, add a seconds field at the front. A six-field expression pasted into a five-field crontab shifts every field by one. Count the fields before you save.
- Nicknames. cronie and Kubernetes accept
@daily,@hourlyand friends. GitHub Actions does not. - Minimum interval. GitHub Actions does not run schedules more often than every 5 minutes, and runs can be delayed at busy times such as the top of the hour.
- Impossible dates.
0 0 30 2 *asks for February 30 and never fires. The generator reports no runs within the next year.
Debugging a schedule
Write the intended rule in plain English first, including the zone: "weekdays at 09:00 America/Sao_Paulo". Translate it to fields, paste the result into the Cron Generator, and read both the sentence and the next five runs. If the sentence contains "whichever comes first", you have hit the day-field OR rule. Then check the runner's zone and whether it uses five or six fields. For the time conversions that come up along the way, the Unix timestamps guide and the Timestamp Converter help.
Open the live tool
Open Cron Expression Generator Related reading: all guides · FAQ.