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 minutes
schedule('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 minutes
schedule('check for updates').cron('0/15 * * * *', async (ctx) => {
console.log('checking for updates')
})
// at 1:00am on the 1st of every month
schedule('delete stale data').cron('0 1 1 * *', async (ctx) => {
console.log('clearing data')
})

Expression format

Nitric uses traditional Unix formatted cron expressions

FieldValues
Minute0-59
Hour0-23
Day (of month)1-31
Month1-12 or JAN-DEC
Day (of week)0-6 or SUN-SAT

Common values

ValueDescription
*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 ExpressionUnix 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.

Last updated on Nov 18, 2024