Skip to content
LastPing
GUIDE · AZURE FUNCTIONS · TIMER TRIGGER · FREE

Monitor Azure Functions timer triggers: detect missed and failed scheduled runs

Azure Functions timer triggers fire on a 6-field NCRONTAB schedule. When a function throws or the host is down, Application Insights logs the exception, but sends no notification unless you've configured alerts, which is non-trivial to set up. A missed run (host offline during the scheduled window) produces nothing at all. One ping call at the end of a successful function execution is the simplest reliable detection.

Your assistant can do this for you

Monitor my Azure Functions with LastPing

On this page
  1. Setup: one HTTP call, about a minute
  2. What this catches
  3. Questions people ask

Setup: one HTTP call, about a minute

Snippets for Python v2, C# isolated worker, and Node.js.

Create a heartbeat monitor in LastPing

In the console, create a monitor. Azure Functions timer uses 6-field NCRONTAB (prepend a seconds field to standard cron). Use the same expression as your function's schedule binding. All times in the NCRONTAB are UTC.

# Azure NCRONTAB — 6 fields: second minute hour day month day-of-week
# "0 0 3 * * *"   → 03:00:00 UTC daily
# "0 */30 * * * *" → every 30 minutes
# "0 0 9 * * 1-5"  → 09:00 UTC weekdays
https://ping.lastping.dev/<your-monitor-id>

Python v2 function: ping on success

Store the monitor ID in an app setting (LASTPING_MONITOR_ID) and call the ping at the end of the successful path.

import os, urllib.request
import azure.functions as func

app = func.FunctionApp()
PING_URL = f"https://ping.lastping.dev/{os.environ['LASTPING_MONITOR_ID']}"

@app.timer_trigger(schedule="0 0 3 * * *", arg_name="mytimer",
                   run_on_startup=False, use_monitor=True)
def nightly_job(mytimer: func.TimerRequest) -> None:
    urllib.request.urlopen(f"{PING_URL}/start", timeout=10)  # overrun detection
    try:
        do_work()
        urllib.request.urlopen(PING_URL, timeout=10)
    except Exception:
        urllib.request.urlopen(f"{PING_URL}/fail", timeout=10)
        raise

C# isolated worker: ping on success

using Microsoft.Azure.Functions.Worker;
using System.Net.Http;

public class NightlyJob
{
    private static readonly HttpClient _http = new();
    private static readonly string _pingUrl =
        $"https://ping.lastping.dev/{Environment.GetEnvironmentVariable("LASTPING_MONITOR_ID")}";

    [Function("NightlyJob")]
    public async Task Run([TimerTrigger("0 0 3 * * *", RunOnStartup = false)] TimerInfo timer)
    {
        await _http.GetAsync($"{_pingUrl}/start");  // arm overrun detection
        try
        {
            await DoWorkAsync();
            await _http.GetAsync(_pingUrl);
        }
        catch
        {
            await _http.GetAsync($"{_pingUrl}/fail");
            throw;
        }
    }
}

Node.js v4 function: ping on success

const { app } = require('@azure/functions');

const PING_URL = `https://ping.lastping.dev/${process.env.LASTPING_MONITOR_ID}`;

app.timer('nightlyJob', {
  schedule: '0 0 3 * * *',
  runOnStartup: false,
  handler: async (myTimer, context) => {
    await fetch(`${PING_URL}/start`);
    try {
      await doWork();
      await fetch(PING_URL);
    } catch (err) {
      await fetch(`${PING_URL}/fail`);
      throw err;
    }
  }
});

Add the app setting in Azure

In the Azure portal: Function App → Configuration → Application settings → + New application setting. Or via Azure CLI:

az functionapp config appsettings set \
  --name my-function-app \
  --resource-group my-rg \
  --settings LASTPING_MONITOR_ID=<your-monitor-id>

What this catches

  • Unhandled exception: /fail fires; incident opens immediately.
  • Function host offline during scheduled window: no invocation, no ping → incident opens on silence.
  • Function timeout (default 5 min, up to 60 min): /start arrived, function killed before success → overrun incident.
  • Deployment broke the function: host restarts and misses the trigger window → silence → incident.
  • Recovery: next successful run closes the incident automatically.

Running on AWS? See AWS Lambda + EventBridge. On GCP? See Google Cloud Scheduler. For the broader concept, see dead-man's switch explained. For AI agent heartbeat monitoring, see the LastPing MCP server.

Questions people ask

Front-loaded answers: the most important fact first.

  • What cron format does Azure Functions use?

    Azure Functions uses a 6-field NCRONTAB expression where the first field is seconds: {second} {minute} {hour} {day} {month} {day-of-week}. This differs from standard 5-field unix cron by prepending a seconds field. Example: 0 0 3 * * * = 03:00:00 UTC daily (second=0, minute=0, hour=3). All times are UTC; there is no per-binding timezone setting (set the function app's WEBSITE_TIME_ZONE app setting to change the host timezone). Set RunOnStartup: false in production to avoid an extra invocation on cold start.

  • Does Azure Functions alert on a missed timer trigger?

    No. Azure Functions does not send a notification if a timer trigger invocation fails or is missed because the function host was down (offline during the scheduled window). If use_monitor=True (Python) or UseMonitor=true (C#) is set, missed invocations are caught up on next host start, but no notification is sent. Application Insights can surface exceptions and failures, but alerting on missed runs (runs that never happened) requires external dead-man's-switch monitoring.

  • What is the difference between RunOnStartup and UseMonitor?

    RunOnStartup=True fires the function immediately when the host starts, regardless of schedule: useful in development, dangerous in production (causes extra invocations on every deployment). UseMonitor=True enables Azure's built-in missed-run catch-up: if the host was offline when the schedule fired, it fires on next startup. Use RunOnStartup=False, UseMonitor=True in production.

  • How do I monitor an Azure Functions timer trigger with LastPing?

    Add one HTTP call at the end of the function body that fires only on success. In Python: import urllib.request; urllib.request.urlopen('https://ping.lastping.dev/<id>', timeout=10). In C#: using var client = new HttpClient(); await client.GetAsync("https://ping.lastping.dev/<id>"). Create a LastPing heartbeat monitor with the same schedule and grace window.

  • Is this free?

    Yes. LastPing is free for individuals with no monitor cap. See vs Healthchecks.io and vs Cronitor.

FREE FOR INDIVIDUALS · FULLY HOSTED

Azure timer triggers fail silently. Add one line to know immediately.

One HTTP call at the end of your function. First alert in under a minute, and LastPing monitors itself the same way.