Timer trigger for Azure Functions
This article explains how to work with timer triggers in Azure Functions. A timer trigger lets you run a function on a schedule.
This is reference information for Azure Functions developers. If you're new to Azure Functions, start with the following resources:
C# developer references:
For information on how to manually run a timer-triggered function, see Manually run a non HTTP-triggered function.
Support for this binding is automatically provided in all development environments. You don't have to manually install the package or register the extension.
Source code for the timer extension package is in the azure-webjobs-sdk-extensions GitHub repository.
Important
This article uses tabs to support multiple versions of the Node.js programming model. The v4 model is currently in preview and is designed to have a more flexible and intuitive experience for JavaScript and TypeScript developers. Learn more about the differences between v3 and v4 in the upgrade guide.
Azure Functions supports two programming models for Python. The way that you define your bindings depends on your chosen programming model.
The Python v2 programming model lets you define bindings using decorators directly in your Python function code. For more information, see the Python developer guide.
This article supports both programming models.
Example
This example shows a C# function that executes each time the minutes have a value divisible by five. For example, when the function starts at 18:55:00, the next execution is at 19:00:00. A TimerInfo
object is passed to the function.
A C# function can be created using one of the following C# modes:
- In-process class library: compiled C# function that runs in the same process as the Functions runtime.
- Isolated process class library: compiled C# function that runs in a process isolated from the runtime. Isolated process is required to support C# functions running on .NET 5.0.
- C# script: used primarily when creating C# functions in the Azure portal.
Important
Support will end for the in-process model on November 10, 2026. We highly recommend that you migrate your apps to the isolated worker model for full support.
//<docsnippet_fixed_delay_retry_example>
[Function(nameof(TimerFunction))]
[FixedDelayRetry(5, "00:00:10")]
public static void Run([TimerTrigger("0 */5 * * * *")] TimerInfo timerInfo,
FunctionContext context)
{
var logger = context.GetLogger(nameof(TimerFunction));
The following example function triggers and executes every five minutes. The @TimerTrigger
annotation on the function defines the schedule using the same string format as CRON expressions.
@FunctionName("keepAlive")
public void keepAlive(
@TimerTrigger(name = "keepAliveTrigger", schedule = "0 */5 * * * *") String timerInfo,
ExecutionContext context
) {
// timeInfo is a JSON string, you can deserialize it to an object using your favorite JSON library
context.getLogger().info("Timer is triggered: " + timerInfo);
}
The following example shows a timer trigger binding and function code that uses the binding, where an instance representing the timer is passed to the function. The function writes a log indicating whether this function invocation is due to a missed schedule occurrence. The example depends on whether you use the v1 or v2 Python programming model.
import datetime
import logging
import azure.functions as func
app = func.FunctionApp()
@app.function_name(name="mytimer")
@app.timer_trigger(schedule="0 */5 * * * *",
arg_name="mytimer",
run_on_startup=True)
def test_function(mytimer: func.TimerRequest) -> None:
utc_timestamp = datetime.datetime.utcnow().replace(
tzinfo=datetime.timezone.utc).isoformat()
if mytimer.past_due:
logging.info('The timer is past due!')
logging.info('Python timer trigger function ran at %s', utc_timestamp)
The following example shows a timer trigger TypeScript function.
import { app, InvocationContext, Timer } from '@azure/functions';
export async function timerTrigger1(myTimer: Timer, context: InvocationContext): Promise<void> {
context.log('Timer function processed request.');
}
app.timer('timerTrigger1', {
schedule: '0 */5 * * * *',
handler: timerTrigger1,
});
The following example shows a timer trigger JavaScript function.
Here's the binding data in the function.json file:
{
"schedule": "0 */5 * * * *",
"name": "myTimer",
"type": "timerTrigger",
"direction": "in"
}
The following is the timer function code in the run.ps1 file:
# Input bindings are passed in via param block.
param($myTimer)
# Get the current universal time in the default string format.
$currentUTCtime = (Get-Date).ToUniversalTime()
# The 'IsPastDue' property is 'true' when the current function invocation is later than scheduled.
if ($myTimer.IsPastDue) {
Write-Host "PowerShell timer is running late!"
}
# Write an information log with the current time.
Write-Host "PowerShell timer trigger function ran! TIME: $currentUTCtime"
Attributes
In-process C# library uses TimerTriggerAttribute from Microsoft.Azure.WebJobs.Extensions whereas isolated worker process C# library uses TimerTriggerAttribute from Microsoft.Azure.Functions.Worker.Extensions.Timer to define the function. C# script instead uses a function.json configuration file.
Attribute property | Description |
---|---|
Schedule | A CRON expression or a TimeSpan value. A TimeSpan can be used only for a function app that runs on an App Service Plan. You can put the schedule expression in an app setting and set this property to the app setting name wrapped in % signs, as %ScheduleAppSetting% . |
RunOnStartup | If true , the function is invoked when the runtime starts. For example, the runtime starts when the function app wakes up after going idle due to inactivity. when the function app restarts due to function changes, and when the function app scales out. Use with caution. RunOnStartup should rarely if ever be set to true , especially in production. |
UseMonitor | Set to true or false to indicate whether the schedule should be monitored. Schedule monitoring persists schedule occurrences to aid in ensuring the schedule is maintained correctly even when function app instances restart. If not set explicitly, the default is true for schedules that have a recurrence interval greater than or equal to 1 minute. For schedules that trigger more than once per minute, the default is false . |
Decorators
Applies only to the Python v2 programming model.
For Python v2 functions defined using a decorator, the following properties on the schedule
:
Property | Description |
---|---|
arg_name |
The name of the variable that represents the timer object in function code. |
schedule |
A NCRONTAB expression or a TimeSpan value. A TimeSpan can be used only for a function app that runs on an App Service Plan. You can put the schedule expression in an app setting and set this property to the app setting name wrapped in % signs, as in this example: "%ScheduleAppSetting%". |
run_on_startup |
If true , the function is invoked when the runtime starts. For example, the runtime starts when the function app wakes up after going idle due to inactivity. when the function app restarts due to function changes, and when the function app scales out. Use with caution. runOnStartup should rarely if ever be set to true , especially in production. |
use_monitor |
Set to true or false to indicate whether the schedule should be monitored. Schedule monitoring persists schedule occurrences to aid in ensuring the schedule is maintained correctly even when function app instances restart. If not set explicitly, the default is true for schedules that have a recurrence interval greater than or equal to 1 minute. For schedules that trigger more than once per minute, the default is false . |
For Python functions defined by using function.json, see the Configuration section.
Annotations
The @TimerTrigger
annotation on the function defines the schedule
using the same string format as CRON expressions. The annotation supports the following settings:
Configuration
Applies only to the Python v1 programming model.
The following table explains the properties that you can set on the options
object passed to the app.timer()
method.
Property | Description |
---|---|
schedule | A NCRONTAB expression or a TimeSpan value. A TimeSpan can be used only for a function app that runs on an App Service Plan. You can put the schedule expression in an app setting and set this property to the app setting name wrapped in % signs, as in this example: "%ScheduleAppSetting%". |
runOnStartup | If true , the function is invoked when the runtime starts. For example, the runtime starts when the function app wakes up after going idle due to inactivity. when the function app restarts due to function changes, and when the function app scales out. Use with caution. runOnStartup should rarely if ever be set to true , especially in production. |
useMonitor | Set to true or false to indicate whether the schedule should be monitored. Schedule monitoring persists schedule occurrences to aid in ensuring the schedule is maintained correctly even when function app instances restart. If not set explicitly, the default is true for schedules that have a recurrence interval greater than or equal to 1 minute. For schedules that trigger more than once per minute, the default is false . |
The following table explains the binding configuration properties that you set in the function.json file.
function.json property | Description |
---|---|
type | Must be set to "timerTrigger". This property is set automatically when you create the trigger in the Azure portal. |
direction | Must be set to "in". This property is set automatically when you create the trigger in the Azure portal. |
name | The name of the variable that represents the timer object in function code. |
schedule | A NCRONTAB expression or a TimeSpan value. A TimeSpan can be used only for a function app that runs on an App Service Plan. You can put the schedule expression in an app setting and set this property to the app setting name wrapped in % signs, as in this example: "%ScheduleAppSetting%". |
runOnStartup | If true , the function is invoked when the runtime starts. For example, the runtime starts when the function app wakes up after going idle due to inactivity. when the function app restarts due to function changes, and when the function app scales out. Use with caution. runOnStartup should rarely if ever be set to true , especially in production. |
useMonitor | Set to true or false to indicate whether the schedule should be monitored. Schedule monitoring persists schedule occurrences to aid in ensuring the schedule is maintained correctly even when function app instances restart. If not set explicitly, the default is true for schedules that have a recurrence interval greater than or equal to 1 minute. For schedules that trigger more than once per minute, the default is false . |
When you're developing locally, add your application settings in the local.settings.json file in the Values
collection.
Caution
Don't set runOnStartup to true
in production. Using this setting makes code execute at highly unpredictable times. In certain production settings, these extra executions can result in significantly higher costs for apps hosted in a Consumption plan. For example, with runOnStartup enabled the trigger is invoked whenever your function app is scaled. Make sure you fully understand the production behavior of your functions before enabling runOnStartup in production.
See the Example section for complete examples.
Usage
When a timer trigger function is invoked, a timer object is passed into the function. The following JSON is an example representation of the timer object.
{
"Schedule":{
"AdjustForDST": true
},
"ScheduleStatus": {
"Last":"2016-10-04T10:15:00+00:00",
"LastUpdated":"2016-10-04T10:16:00+00:00",
"Next":"2016-10-04T10:20:00+00:00"
},
"IsPastDue":false
}
{
"schedule":{
"adjustForDST": true
},
"scheduleStatus": {
"last":"2016-10-04T10:15:00+00:00",
"lastUpdated":"2016-10-04T10:16:00+00:00",
"next":"2016-10-04T10:20:00+00:00"
},
"isPastDue":false
}
The isPastDue
property is true
when the current function invocation is later than scheduled. For example, a function app restart might cause an invocation to be missed.
NCRONTAB expressions
Azure Functions uses the NCronTab library to interpret NCRONTAB expressions. An NCRONTAB expression is similar to a CRON expression except that it includes an additional sixth field at the beginning to use for time precision in seconds:
{second} {minute} {hour} {day} {month} {day-of-week}
Each field can have one of the following types of values:
Type | Example | When triggered |
---|---|---|
A specific value | 0 5 * * * * |
Once every hour of the day at minute 5 of each hour |
All values (* ) |
0 * 5 * * * |
At every minute in the hour, during hour 5 |
A range (- operator) |
5-7 * * * * * |
Three times a minute - at seconds 5 through 7 during every minute of every hour of each day |
A set of values (, operator) |
5,8,10 * * * * * |
Three times a minute - at seconds 5, 8, and 10 during every minute of every hour of each day |
An interval value (/ operator) |
0 */5 * * * * |
12 times an hour - at second 0 of every 5th minute of every hour of each day |
To specify months or days you can use numeric values, names, or abbreviations of names:
- For days, the numeric values are 0 to 6 where 0 starts with Sunday.
- Names are in English. For example:
Monday
,January
. - Names are case-insensitive.
- Names can be abbreviated. Three letters is the recommended abbreviation length. For example:
Mon
,Jan
.
NCRONTAB examples
Here are some examples of NCRONTAB expressions you can use for the timer trigger in Azure Functions.
Example | When triggered |
---|---|
0 */5 * * * * |
once every five minutes |
0 0 * * * * |
once at the top of every hour |
0 0 */2 * * * |
once every two hours |
0 0 9-17 * * * |
once every hour from 9 AM to 5 PM |
0 30 9 * * * |
at 9:30 AM every day |
0 30 9 * * 1-5 |
at 9:30 AM every weekday |
0 30 9 * Jan Mon |
at 9:30 AM every Monday in January |
Note
NCRONTAB expression supports both five field and six field format. The sixth field position is a value for seconds which is placed at the beginning of the expression. If the CRON expression is invalid the Azure Portal Function Test will display a 404 error, if Application Insights is connected more details are logged there.
NCRONTAB time zones
The numbers in a NCRONTAB expression refer to a time and date, not a time span. For example, a 5 in the hour
field refers to 5:00 AM, not every 5 hours.
The default time zone used with the CRON expressions is Coordinated Universal Time (UTC). To have your CRON expression based on another time zone, create an app setting for your function app named WEBSITE_TIME_ZONE
.
The value of this setting depends on the operating system and plan on which your function app runs.
Operating system | Plan | Value |
---|---|---|
Windows | All | Set the value to the name of the desired time zone as given by the second line from each pair given by the Windows command tzutil.exe /L |
Note
WEBSITE_TIME_ZONE
is not currently supported on the Linux Consumption plan.
For example, Eastern Time in the US (represented by Eastern Standard Time
(Windows) or America/New_York
(Linux)) currently uses UTC-05:00 during standard time and UTC-04:00 during daylight time. To have a timer trigger fire at 10:00 AM Eastern Time every day, create an app setting for your function app named WEBSITE_TIME_ZONE
, set the value to Eastern Standard Time
(Windows) or America/New_York
(Linux), and then use the following NCRONTAB expression:
"0 0 10 * * *"
When you use WEBSITE_TIME_ZONE
the time is adjusted for time changes in the specific timezone, including daylight saving time and changes in standard time.
TimeSpan
A TimeSpan
can be used only for a function app that runs on an App Service Plan.
Unlike a NCRONTAB expression, a TimeSpan
value specifies the time interval between each function invocation. When a function completes after running longer than the specified interval, the timer immediately invokes the function again.
Expressed as a string, the TimeSpan
format is hh:mm:ss
when hh
is less than 24. When the first two digits are 24 or greater, the format is dd:hh:mm
. Here are some examples:
Example | When triggered |
---|---|
"01:00:00" | every hour |
"00:01:00" | every minute |
"25:00:00:00" | every 25 days |
"1.00:00:00" | every day |
Scale-out
If a function app scales out to multiple instances, only a single instance of a timer-triggered function is run across all instances. It will not trigger again if there is an outstanding invocation still running.
Function apps sharing Storage
If you are sharing storage accounts across function apps that are not deployed to app service, you might need to explicitly assign host ID to each app.
Functions version | Setting |
---|---|
2.x (and higher) | AzureFunctionsWebHost__hostid environment variable |
1.x | id in host.json |
You can omit the identifying value or manually set each function app's identifying configuration to a different value.
The timer trigger uses a storage lock to ensure that there is only one timer instance when a function app scales out to multiple instances. If two function apps share the same identifying configuration and each uses a timer trigger, only one timer runs.
Retry behavior
Unlike the queue trigger, the timer trigger doesn't retry after a function fails. When a function fails, it isn't called again until the next time on the schedule.
Manually invoke a timer trigger
The timer trigger for Azure Functions provides an HTTP webhook that can be invoked to manually trigger the function. This can be extremely useful in the following scenarios.
- Integration testing
- Slot swaps as part of a smoke test or warmup activity
- Initial deployment of a function to immediately populate a cache or lookup table in a database
Please refer to manually run a non HTTP-triggered function for details on how to manually invoke a timer triggered function.
Troubleshooting
For information about what to do when the timer trigger doesn't work as expected, see Investigating and reporting issues with timer triggered functions not firing.