Cron Job Syntax: A Complete Guide with Examples
Cron is one of those tools that has been around since the 1970s and shows no signs of going away. Whether you are scheduling database backups, sending weekly email digests, or triggering CI pipeline steps, you will eventually need to write a cron expression. The syntax looks cryptic at first, but there are really only a handful of rules to learn.
The Five-Field Structure
A standard cron expression has five space-separated fields:
ββββββββββββ minute (0β59)
β ββββββββββ hour (0β23)
β β ββββββββ day of month (1β31)
β β β ββββββ month (1β12)
β β β β ββββ day of week (0β7, 0 and 7 = Sunday)
β β β β β
* * * * *
Some systems (like Quartz Scheduler in Java, AWS EventBridge, and Spring's @Scheduled) add a sixth field for seconds at the start, making it a six-field expression. Standard Unix/Linux cron (crontab), GitHub Actions, and most cloud schedulers use the five-field form.
Special Characters
* (Asterisk) β Every value
* means "every possible value" in that field. * * * * * runs every minute of every day.
, (Comma) β List of values
Comma separates a list of discrete values. 0 9,17 * * * runs at 9:00 AM and 5:00 PM.
- (Hyphen) β Range
Hyphen defines an inclusive range. 0 9 * * 1-5 runs at 9:00 AM Monday through Friday.
/ (Slash) β Step
Slash defines a step. */15 in the minute field means "every 15 minutes": 0, 15, 30, 45. 0 8-18/2 * * * runs every 2 hours between 8 AM and 6 PM.
L β Last (day fields only)
L in the day-of-month field means the last day of the month. 0 0 L * * runs at midnight on the last day of every month.
W β Nearest weekday (day-of-month only)
15W means the nearest weekday to the 15th. If the 15th is a Saturday, it runs on Friday the 14th.
# β Nth weekday (day-of-week only)
2#1 means the first Monday of the month. 5#3 means the third Friday.
Named months and weekdays
Instead of numbers you can use three-letter abbreviations: JANβDEC for months and SUNβSAT for weekdays. 0 0 * JAN,JUL MON runs at midnight every Monday in January and July.
30 Practical Examples
| Expression | Description |
|---|---|
* * * * * | Every minute |
*/5 * * * * | Every 5 minutes |
*/15 * * * * | Every 15 minutes |
0 * * * * | Every hour (at :00) |
0 */2 * * * | Every 2 hours |
0 0 * * * | Every day at midnight |
0 12 * * * | Every day at noon |
0 9 * * 1-5 | 9:00 AM weekdays only |
0 0 * * 0 | Every Sunday at midnight |
0 0 1 * * | First day of each month |
0 0 L * * | Last day of each month |
0 0 1 1 * | Once a year β 1 January |
0 8-18 * * 1-5 | Every hour, 8 AMβ6 PM, weekdays |
30 9 * * 1 | 9:30 AM every Monday |
0 0 15W * * | Nearest weekday to the 15th |
Common Mistakes
Day-of-month vs day-of-week conflict
When both the day-of-month and day-of-week fields are non-asterisk, many cron implementations run the job if either condition matches (OR logic, not AND). 0 0 13 * 5 runs at midnight on the 13th of the month and also every Friday β not only on Friday the 13th. To get AND behaviour, you need to handle it in your script.
Month is 1-indexed, not 0-indexed
January is 1, not 0. Writing 0 0 1 0 * is invalid; use 0 0 1 1 * for January.
Timezone is the server's local timezone
Standard cron uses the system's local timezone. If your server is in UTC and your users are in New York (UTC-5), a job at 0 9 * * * runs at 4 AM New York time. Use CRON_TZ=America/New_York (supported in many modern cron implementations) or convert times manually.
Missing run-lock for long jobs
If a cron job takes longer than its interval, the next invocation will start a second instance concurrently. Use a file lock (flock) or check for an existing process before starting work.
Testing Your Expressions
Before deploying a cron schedule to production, always verify it produces the times you expect. A parser tool lets you see the next 5β10 scheduled executions in human-readable form, catching off-by-one errors in ranges or incorrect day-of-week numbering before they cause an incident at 3 AM.