Schedules
Nitric provides schedules support for writing services that process batch tasks, reporting and other work that happens on a set cadence.
The schedule
resource lets you define named schedules, including their frequency or cron expression and a callback to run on that schedule.
If you're looking for a way to perform once-off work at some point in the future, use delayed messaging instead of schedules.
Creating schedules
There are two ways to define schedules. Using every
allows simple rate definitions to trigger the callback or cron
can be used for more complex scenarios.
Here are a couple of example schedules that use both definition types:
import { schedule } from '@nitric/sdk'// Run every 5 minutesschedule('process-transactions').every('5 minutes', async (ctx) => {console.log(`processing at ${new Date().toLocaleString()}`)})// Run at 22:00 Monday through Friday.schedule('send-reminder').cron('0 22 * * 1-5', async (ctx) => {console.log(`reminder at ${new Date().toLocaleString()}`)})
Using every
Using every
allows for expressive schedules which run a callback as often as once per minute. The description of how often to run a schedule is known as it's rate
.
Here are some example rate-based schedules:
import { schedule } from '@nitric/sdk'schedule('process-often').every('5 minutes', async (ctx) => {console.log(`processing at ${new Date().toLocaleString()}`)})schedule('process-sometimes').every('2 hours', async (ctx) => {console.log(`processing at ${new Date().toLocaleString()}`)})schedule('process-rarely').every('30 days', async (ctx) => {console.log(`processing at ${new Date().toLocaleString()}`)})
Rates
Valid rates include a number followed by a frequency value e.g. 5 minutes
. The valid frequencies are minutes
, days
and months
.
In all cases the frequencies can be singular or plural, so 1 day
and 1 days
are equivalent.
Using cron
Using cron
allows for finer control of how frequently your schedules run.
The most frequently a schedule can run is once per minute, for this reason Nitric uses 5 field cron expressions with values for minute, hour, day of month, month and day of week.
Here are some example cron-based schedules:
import { schedule } from '@nitric/sdk'// every 15 minutesschedule('check for updates').cron('0/15 * * * *', async (ctx) => {console.log('checking for updates')})// at 1:00am on the 1st of every monthschedule('delete stale data').cron('0 1 1 * *', async (ctx) => {console.log('clearing data')})
Expression format
Nitric uses traditional Unix formatted cron expressions
Field | Values |
---|---|
Minute | 0-59 |
Hour | 0-23 |
Day (of month) | 1-31 |
Month | 1-12 or JAN-DEC |
Day (of week) | 0-6 or SUN-SAT |
Common values
Value | Description |
---|---|
* | Wildcard (any value) |
, | List separator |
- | Value range |
/ | Step values |
Timezones
To ensure your schedules run when you expect it's important to know what timezone they're being applied in. Nitric allows you to set a schedule-timezone
per deployed environment (stack) on supported providers.
See stack configuration docs for how to set the schedule-timezone
property:
If a timezone is not configured the default for the target provider/region will be used, this is often Universal Coordinated Time (UTC).
Provider specific notes
Schedules on AWS
If you're familiar with AWS services that support cron expressions (such as EventBridge) you're probably aware that they use an alternate expression format which is incompatible with the traditional Unix format.
AWS cron expression should not be used with Nitric. Instead, Nitric will automatically convert standard Unix expressions into AWS expressions during deployment.
Converting from AWS
AWS cron expressions expect a value between 1-7 to represent day of week, while Unix expressions use a value between 0-6. Additionally, AWS expressions contain an additional (6th) field for Year (with a value between 1970-2199). Lastly, they expect a special ?
wildcard character in either the day of week or day of month field.
To convert an AWS expression to a standard Unix expression you need to do the following:
- Reduce any day of week values by 1
- Remove the year field
- Replace
?
with*
Here are some examples:
AWS Expression | Unix Expression (Nitric) |
---|---|
0 10 * * ? * | 0 10 * * * |
0 18 ? * 1-5 * | 0 18 * * 0-4 |
0 18 ? * MON-FRI * | 0 18 * * MON-FRI |
If you're using the year
field to control which years your expressions
execute this should be moved to logic in the callback function instead.
Schedules on Azure
Schedules deployed to Azure with Nitric's default Azure provider will use Container Apps to run the schedule callback. The schedule trigger is defined as a Dapr Cron Binding. Due to the way this service operates Nitric will configure the minimum container instances to 1 to ensure there is always a container available to run the schedule callback.
If you're using schedules on Azure you will be charged for at least 1 container instance per handler containing a schedule. For this reason, when your application requires multiple schedules, it can be cost effective to use a single handler file with several schedule definitions.
This may change in the future as Nitric's Azure provider evolves, allowing for scale to zero as is the case with other providers.
Cloud Service Mapping
Each cloud provider comes with a set of default services used when deploying resources. You can find the default services for each cloud provider below.