Handling different types of cron jobs using Schedule Expressions with AWS

codetelo
5 min readNov 17, 2022
AWS Cron Jobs Made Easy

I’ve been working on a few different cron jobs recently and one of things I’ve come up against is just making no-nonsense scheduled cron jobs. I’ve noticed that some of the things I was working on just weren’t documented as clearly as I’d like them to be and I figured I would share a couple of different common schedule expressions that I’ve had to use.

Schedule Expressions

There are two types of schedule expressions that are used in AWS, rate or cron. All of the expressions are defined as strings which are parsed and stored on EventBridge, then later executed when the timed trigger is met. https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule-schedule.html

Rate

When we use rate, it’s defined as a frequency by which your lambda or other service is invoked by EventBridge. Rate is a function that takes a positive integer and a frequency.

Possible Frequencies

minute|minutes|hour|hours|day|days

The rate definition looks like the following:

rate(value unit)

So, all you have to do to define this is:

Every minute: rate(1 minute)
Every 30 minutes: rate(30 minutes)
Every hour: rate(1 hour)
Every 12 hours: rate(12 hours)
Every day: rate(1 day)
Every week: rate(7 days)
Every two weeks: rate(14 days)
Every three weeks: rate(21 days)

Keep in mind the pluralities of the different units. It should match the value. So, you can’t do something like rate(1 months) or rate(2 hour) .

Super simple, right? But what if you need to do something a little more complex, like you need a very specific time or you want to execute on a specific day of the week or month. That’s where cron jobs come in, but it’s also where things can be a little trickier.

Cron

Crons are scheduled jobs that can execute your lambda or other services using EventBridge. The formatting of crons is a little different and more complex than the rates. If you wanted to define a cron it takes the following format:

cron(Minutes Hours Day-of-month Month Day-of-week Year)

Here’s a few common definitions that I’ve had to use in the past:

Every day(at 11:59pm): cron(59 23 * * ? *)

Every week(on Sunday at 11:59pm): cron(59 23 ? * SUN *)

Every quarter(AKA 3 months): cron(0 0 * */3 ? *)

Every year on January first: cron(0 0 1 1 * *)

Depending on your use case things might get more or less complex, but the chart below should help you a little bit with coming up with your cron definition:


Minutes | Hours | Day of Month | Month | Day of Week | Year
---------|-------|--------------|-----------------|----------------|-----------
0-59 | 0-23 | 1-31 | 1-12 or JAN-DEC | 1-7 or SUN-SAT | 1970-2199

There are also wildcards that can be used in certain situations.

Comma

Commas are used to define multiple values for a particular field value. For instance, if you wanted it to run on two different months like both January and March , then you could write them as a comma separated value:

Every January 1st and March 1st: cron(* * 1 JAN,MAR ? *)

Dash

Dashes are used to denote a range of values. For example if I wanted to run every single day of the month between the 1st and the 15th:

Everyday between the1st and 15th of every month: cron(* * 1-15 * ? *)

Asterisk

As per usual, the asterisk includes all of the possible values in the list.

Everyday at 12pm: cron(0 12 * * ? *)

Forward Slash

The forward slash allows for increments. For months, you can do increments of 3 by using */3 , as shown in my example above for the quarterly cron job.

Question Mark

The question mark is used as a placeholder for any. This is used due to one of the limitations explained below. You can only define either day of the month or day of the week since they could be conflicting values. The days of the month don’t necessarily fall on the day of the week. In many of the examples above, you can see this in use.

L

L stands for the last day of either the week or month. It can be used with day of the month or day of the week. All you need to do is append the L to your value.

Last day of the month every month: cron(* * 3L * ? *)

Last day of the week every week: cron(* * ? * 3L *)

W

W stands for weekday. In the day of month field you can use this to define specific weekdays within the month. This is perfect for times when you need notifications to go out during a work week.

Every weekday closest to the 15th of the month: cron(* * 15W * ? *)

#

The # symbol is used in the day of the week field to a specific occurrence of a day within a month. For example, the 3rd Wednesday of a month. The syntax for this is day-of-the-week#occurrence-within-month .

Every 3rd Wednesday of the month: cron(* * ? * 4#3 *)

List of all Wildcards relative to their fields


Field | Wildcards
--------------|---------------
Minutes | , - * /
Hours | , - * /
Day of Month | , - * ? / L W
Month | , - * /
Day of Week | , - * ? L #
Year | , - * /

Limitations

Let’s talk about the limitations of the cron function.

  1. The day of week field can only use one expression. I.E. you can’t combine 3#4,3#5 .
  2. As mentioned above, you can only specify either the day of the month or the day of the week because they could be conflicting. The 2nd of every month isn’t a Tuesday. So, when you define one of them, you’ll need to use a ? for the other one.
  3. Cron expressions can’t fire off at rates that are less than 1 minute.

Hopefully, this article will help assist on the understanding of scheduled events in AWS using EventBridge. I know that all of this information is freely available through AWS Documentation, but I sometimes find that hard to read.

If there are any scheduled cron jobs that you have questions about please ask in the comments! I’m hoping to be able to write more content about AWS, Serverless Stack(SST), Typescript, React, and much more. I’m also thinking about making a package that will export human readable variables that contain different cron settings. Let me know if that’s something that you’d like to use.

This is my first published article, so please let me know if there is anything I can do to improve readability or if there are subjects that you’d like to know about. Thanks for sticking around to the end!

--

--

codetelo

Full Stack Software Engineer | Tech Lead | Typescript | React | AWS