Cron is how Unix-like systems have scheduled repeating tasks for decades, and its five-field syntax still powers everything from nightly backups to CI pipelines and serverless triggers. The syntax looks cryptic the first time you meet it, but it follows a simple, consistent pattern. Once it clicks, you can read and write any schedule at a glance.
The Five Fields
A standard cron expression is five fields separated by spaces, each describing one unit of time:
* * * * *
| | | | |
| | | | +-- Day of week (0-6, Sunday = 0)
| | | +---- Month (1-12)
| | +------ Day of month (1-31)
| +-------- Hour (0-23)
+---------- Minute (0-59)Read left to right, the fields go from smallest unit (minute) to largest (day of week). A single asterisk in a field means "every" value for that field. So * * * * * means every minute of every hour of every day, the most frequent schedule cron allows.
The Four Operators
Each field accepts the same four building blocks. Learn these and you can express almost any schedule.
Asterisk: every value
* matches all values. In the hour field it means every hour; in the month field, every month.
Comma: a list
1,15,30 in the minute field means at minute 1, 15, and 30. Use it to pick specific, non-sequential values.
Hyphen: a range
9-17 in the hour field means every hour from 9am through 5pm inclusive. Ranges and lists combine: 9-17 with a step covers business hours neatly.
Slash: a step
*/15 in the minute field means every 15 minutes (0, 15, 30, 45). The number after the slash is the interval. You can apply a step to a range too: 0-30/10 means minute 0, 10, 20, 30.
Reading Real Examples
The fastest way to internalize cron is to translate complete expressions. Here are schedules you will actually encounter:
0 0 * * *— at 00:00 every day. A daily midnight job.*/5 * * * *— every 5 minutes. Common for health checks and polling.0 9 * * 1-5— at 9:00am, Monday to Friday. A weekday morning task.30 2 * * 0— at 2:30am every Sunday. A weekly maintenance window.0 0 1 * *— at midnight on the 1st of every month. A monthly billing or report job.0 */6 * * *— every 6 hours, on the hour (00:00, 06:00, 12:00, 18:00).
Notice the pattern: a value in the minute and hour fields pins the exact time, while asterisks in the date fields let it repeat. To make a job less frequent, you move specificity into the larger fields.
The Day-of-Week and Day-of-Month Gotcha
This is the single most common source of cron bugs. When you specify both the day-of-month field and the day-of-week field (neither is an asterisk), most cron implementations treat them as an OR, not an AND. The job runs when either condition matches.
So 0 0 1 * 1 does not mean "midnight on the 1st only if it is a Monday." It means "midnight on the 1st of the month, AND every Monday." If you need a job to run only on, say, the first Monday of the month, plain cron cannot express that in one expression. You handle the extra condition inside your script instead, usually with a date check at the top.
Time Zones: Know What Clock You Are On
Cron runs against the system's local time zone unless configured otherwise. This bites teams when a server is set to UTC but everyone assumes local time, so the "9am report" arrives at what feels like the middle of the night. Two practical rules help: run servers in UTC and do the mental conversion deliberately, and remember that daylight saving transitions can cause a job to run twice or be skipped on the changeover day. For anything time-sensitive, confirm the box's time zone before trusting the schedule.
Nicknames and Extensions
Many cron implementations support convenient shorthands that replace the five fields entirely: @hourly, @daily (midnight), @weekly (Sunday midnight), @monthly, @yearly, and @reboot (once at startup). They are easier to read, but they give up control over the exact minute. Some systems also add a sixth field for seconds at the front, and platforms like AWS and Quartz extend the syntax further, so always check which dialect your scheduler uses before copying an expression from elsewhere.
How to Avoid Cron Mistakes
- Build the expression field by field rather than guessing the whole thing at once.
- Translate it back into a plain sentence and check it matches your intent.
- Watch the day-of-week and day-of-month OR behavior.
- Confirm the server's time zone, especially around daylight saving.
- Test a frequent version first, then dial it down to the real schedule.
Build and Check Cron Expressions
The safest way to get a schedule right is to build it visually and read the human-language description back before you deploy it. Generate a valid cron expression from plain options, no memorizing required, directly in your browser.