Timer Trigger

How It Works

The Timer trigger uses a CRON expression to define the schedule. The CRON expression is a string that specifies the time and date fields. Azure Functions supports a specific format for CRON expressions:

"{second} {minute} {hour} {day} {month} {day-of-week}"

You can use wildcards (*) and specific values. For example, to run a function every minute:

"0 * * * * *"

To run a function at 10:00 AM every day:

"0 0 10 * * *"

Configuration

The Timer trigger is configured in the function.json file for your function. Here's an example:

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "mytimer",
      "type": "timerTrigger",
      "direction": "in",
      "schedule": "0 */5 * * * *"
    }
  ]
}

In this example:

Run on Startup

By default, the Timer trigger does not run when an Azure Function app is first deployed or scaled up. To enable this behavior, you can set the runOnStartup property to true in function.json:

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "mytimer",
      "type": "timerTrigger",
      "direction": "in",
      "schedule": "0 */5 * * * *",
      "runOnStartup": true
    }
  ]
}

Sample Code

Python

function.json:

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "mytimer",
      "type": "timerTrigger",
      "direction": "in",
      "schedule": "0 */1 * * * *"
    }
  ]
}

__init__.py:

import datetime
import logging

import azure.functions as func

def main(mytimer: func.TimerRequest) -> None:
    utc_timestamp = datetime.datetime.utcnow().isoformat()

    if mytimer.past_due:
        logging.info('The timer is past due!')

    logging.info('Python timer trigger function executed at %s', utc_timestamp)

C#

TimerTrigger.cs:

using System;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace FunctionApp1
{
    public class TimerTrigger
    {
        private readonly ILogger _logger;

        public TimerTrigger(ILogger logger)
        {
            _logger = logger;
        }

        [Function("TimerTrigger")]
        public void Run([TimerTrigger("0 */1 * * * *")] TimerInfo myTimer)
        {
            _logger.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");

            if (myTimer.PastDue)
            {
                _logger.LogInformation("Timer is past due.");
            }
        }
    }
}

JavaScript

function.json:

{
  "scriptFile": "index.js",
  "bindings": [
    {
      "name": "myTimer",
      "type": "timerTrigger",
      "direction": "in",
      "schedule": "0 */1 * * * *"
    }
  ]
}

index.js:

module.exports = async function (context, myTimer) {
    const timeStamp = new Date().toISOString();

    if (myTimer.isPastDue) {
        context.log('JavaScript timer trigger function is past due!');
    }
    context.log('JavaScript timer trigger function executed at: ', timeStamp);
};

Handling Past Due Triggers

If your function app is down or experiences a delay, a timer trigger might become "past due". The TimerRequest object (or equivalent in other languages) has a property like past_due or isPastDue that you can check to handle these situations. You might choose to run the task immediately or log a warning.

Advanced Scheduling with NCrontab

For more complex scheduling needs, consider using the NCrontab library. You can define schedules with more expressive syntax. However, be aware that Azure Functions natively supports the standard CRON format.

Important: The timer trigger is a pull binding. This means that Azure Functions polls the timer service on a schedule. If your function app is scaled down to zero, timers will not fire until the app scales up again.
Tip: Use the Azure Functions Core Tools to test your timer triggers locally. You can simulate different CRON schedules to ensure they behave as expected.