Cron is such a simple yet complex way of expressing schedules. In this short post I'll show you all you need to be able to understand and write cron expressions that cover almost 90+% of the cases.
Before we move on, I want to invite you to visit 0dev, an open-source data platform that works with natural language. Use 0dev to access your data without complex SQL queries, visualize it without any coding and generate insights without any data science experience.
Repository: https://github.com/0dev-hq/0dev
Basic Structure
A cron expression has five (or more) fields:
* * * * *
| | | | |
| | | | └─── Day of the week (0-7, where 0 and 7 both represent Sunday)
| | | └────── Month (1-12)
| | └───────── Day of the month (1-31)
| └──────────── Hour (0-23)
└─────────────── Minute (0-59)
You can memorize it as MHDMD
. Not catchy but it helps!
Note: The values of the Day of the week can be numbers 0-7 or MON-SUN. Also the Month can be expressed as numbers 1-12 or JAN-DEC.
Setting Fixed Times
Each position can be set to a specific value:
0 9 * * * - Runs at 9:00 AM every day.
30 14 * * * - Runs at 2:30 PM every day.
Using Wildcards (*)
The * symbol represents "any" for that position:
* * * * * - Runs every minute of every hour of every day.
0 * * * * - Runs at the beginning of every hour, every day.
Specifying Multiple Values
You can specify multiple values for any position using commas:
0,15,30,45 * * * * - Runs every 15 minutes on the hour, at 15, 30, and 45.
0 9,17 * * * - Runs at 9:00 AM and 5:00 PM every day.
Using Ranges
Ranges are specified with a dash -. You can read it as from n/nth to m/mth
0 9-17 * * * - Runs every hour from 9 AM to 5 PM.
15 14 1-7 * * - Runs at 2:15 PM on the first seven days of each month.
Step Values (/)
Steps allow you to specify intervals. You can read it as every n or nth
.
*/15 * * * * - Runs every 15 minutes.
0 */3 * * * - Runs every 3 hours, at the top of the hour.
0 0 1 */2 * - Runs at midnight on the first day of every other month.
Day-Specific and Month-Specific Scheduling
You can use specific days by setting either:
* * ? * 1 - Runs every Monday.
0 9 ? * MON-FRI - Runs at 9:00 AM, Monday through Friday.
Notice that I'm using ?
instead of *
, which is a matter of preference. While both ? and * work similarly, ? is often used to emphasize that we don’t care about a particular field—in this case, the day of the month. By using ?, we make it clear that only the day of the week (e.g., Monday or Monday through Friday) is relevant to this schedule.
For instance:
0 12 15 * ? - Runs at 12:00 PM on the 15th of every month, with ? indicating that the specific day of the week is irrelevant.
0 12 ? * MON - Runs every Monday at 12:00 PM, with ? indicating that the specific day of the month is irrelevant.
Using ? is helpful when setting up schedules that depend solely on either the day of the week or the day of the month, as it makes the intention of the cron expression clearer.
Cron expression with 6 and 7 fields
If supported, you can add a field to the very right to indicate the year, or a field to the very left to indicate the second.
For instance:
30 20 12 * * * - Runs at exactly 12:20:30 PM every day.
0 0 12 15 6 ? 2024 - Runs at exactly 12:00:00 PM on June 15, 2024.
While I didn't cover every thing about the cron expressions, I hope you know better understand them and can easily write your own expressions.
If you're familiar with the cron expressions, what options would you add to this post? Share them in the comments so others can learn from it.
Happy coding :)