Anatomy of a Cron Expression


by Thomas Tran



A cron job is a way to run repetitive tasks on a schedule in Unix-like operating systems. Cron jobs are often used by many apps to run tasks such as sending mass emails, cleaning up data, updating information in a database tables, amongst other important tasks. Almost everything can be automated with cron jobs - well, almost anything!

In .NET Core, a popular library that can abstract this is called Quartz Scheduler. Similar libraries exist for all popular languages, such as django-crontab for Django, and Rake tasks for Ruby on Rails.

In order to schedule a cron job, you’ll need to provide a cron expression in order to tell the operating system how often the job should run. In this article, we’ll explore the syntax for the cron expression and hopefully walk away with a better understanding of the cron expression.

The cron expression: does it look alien to you?

This is an example cron expression:

0 0 * * *

Does it look alien to you? Because it sure as heck looked alien to me when I first saw one a few years ago! What the above expression is saying is to run the scheduled task every day at 12:00AM, midnight. What a very convoluted way of saying this, right? You may think so, but the computer has no way of understanding human language, so you have to write it in a way that the computer can understand. That’s why we have to write a cron expression in the above syntax so that the computer can understand.

The cron expression has five fields, each represented by an asterisk to determine the date and time of a certain task set to perform repeatedly. These fields are:

<second> <minute> <hour> <day-of-month> <month> <day-of-week> <year (optional)> 
  • Seconds - seconds of the minute the task will run, ranging from 0 to 59.
  • Minute - minute of the hour the task will run on, ranging from 0 to 59.
  • Hour - on what hour the task will run on, ranging from 0 to 23.
  • Day of the month - on what day of the month you want the task to run, ranging from 1 to 31.
  • Month - on what month will the specified task will run on, ranging from 1 to 12.
  • Day of the week - on what day of the week you want a task run, ranging from 0 to 7.
  • Year (optional) - during what year this task will run, ranging from 1970 to 2199.

Furthermore, there are several special characters that may appear in the cron expression:

  • * (all) - asterisk - this character specifies that the task should happen for every time unit. For every, in the minute field, the asterisk means “for every minute”.
  • ? (any) - question mark - this character is used in the <day-of-month> and <day-of-week> fields to say that we don’t care about what value it is. For instance we we want to run a task on the 20th day of the month, regardless of the day of the week, then we specify a ? in the <day-of-the-week field.
  • - (range) - dash - the dash specifies a value range. For instance 0-5 in the hour field means any hour between 0 and 5.
  • , (values) - specifies multiple values. For instance, “MON,WED,FRI” in <day-of-week> field means on the days “Monday, Wednesday, and Friday”.
  • L (last) - means the last of that field. For instance, in the <day-of-week> field, it means the last day of the week. In the <day-of-month> field, it means the last day of the month.
  • / (forward slash) - used to specify increments. For example “0/15” in the seconds field means “the seconds 0, 15, 30, and 45”. And “5/15” in the seconds field means “the seconds 5, 20, 35, and 50”. You can also specify ‘/’ after the ‘’ character - in this case ‘’ is equivalent to having ‘0’ before the ‘/’.
  • W (weekday) - used to specify the weekday (Monday - Friday) nearest the given day. For instance, 15W means the “nearest weekday to the 15th of the month”.

There are a couple other special characters, but these are the main ones that you should know.

Special characters chart

The following chart specifies which special characters are allowed for each field. This may be useful to you for reference:

Field Order Field Name Mandatory Allowed Values Allowed Special Characters
1 Seconds YES 0-59 ,-*/
2 Minutes YES 0-59 ,-*/
3 Hours YES 0-23 ,-*/
4 Day of Month YES 1-31 ,-*?/LW
5 Month YES 1-13 or JAN-DEC ,-*/
6 Day of week YES 1-7 or SUN-SAT ,-*?/L#
7 Year NO Empty, 1970-2099 ,-*/

Building basic cron expressions

Let’s try our hands at building some basic cron expressions.

As you know, the following expression means to run every second:

* * * * * *

If we use the values (,) special character in the <second> field, then we can specify the seconds during which a task should run:

15,30,45 * * * * *

The above says that the task should run at 15, 30, and 45 seconds past the minute. So, within the minute, the task will run 3 times.

Another expression we can use is

0 0 * * * *

which tells the task to run at second 0, minute 0, every hour. Basically, it’s saying telling the task to run every hour, on the dot.

0 0 0 * * *

The above expression says to run the task at 0 second, 0 minute, 0 hour every day of the month, every month, and every day of the year. So essentially it’s telling the task to run every day at 12:00AM (midnight).

Let’s look at another basic expression:

0 0 12 ? * SAT

The above expression says to run the task at 0 second, 0 minute, at the 12th hour, any day of the month (indicated by the ? special character), every month, on Saturday only. So, basically, it’s running the task every Saturday at noon.

Advanced cron expressions

The above cron expressions will most likely be sufficient for the majority of cases. However, there will be times when we need more advanced cron expressions to suit our needs. Now that we’ve gotten a grasp onto the basic cron expressions, let’s try our hands at those advanced ones!

What do you suppose the following expression means?

0 59 23 31 12 ?

Let’s break it down. It’s telling us that the task will run at second 0, minute 59, hour 23, day 31, month 12, any day of the week. So, ignoring the the day of the week, this task will run at the last minute of the last month of the year, and will execute at 11:59pm on December 31st, one minute before the new year! Cool, huh?

The following expression is another synonym for the one above:

0 59 23 L 12 ?

It’s telling us that the task will run on the last day of the month (indicated by the special character L) in December at 11:59pm, which is the same as the other expression we’ve seen before.

What about this expression? What does it mean?

0 */15 */6 ? * 2-6

This expression is telling us that the task will run at second 0, every 15 minutes starting at minute 0, every 6 hours starting at hour 0, any day of the month, every month, but only on the second day of the week through the sixth day of the week. In other words, it’s saying that the task will run at the following times Monday through Friday:

0:00am, 00:15am, 00:30am, 00:45am
06:00am, 06:15am, 06:30am, 06:45am
12:00pm, 12:15pm, 12:30pm, 12:45pm
18:00pm, 18:15pm, 18:30pm, 18:45pm

Cool, huh?

I hope that, armed with the knowledge of the anatomy of a cron expression, that you will be empowered to create special tasks that will be useful to you and others!