CronPup

← Guides

Monitoring Celery beat periodic tasks

With Celery, two things can fail quietly: the beat process (which schedules periodic tasks) and the workers (which run them). If beat dies, nothing is enqueued and nothing errors. If workers are stuck, tasks pile up in the broker. Either way, your "nightly" task just doesn't happen.

Ping from the task

The simplest reliable check is a heartbeat at the end of the periodic task, because it proves that beat scheduled it and a worker ran it:

import urllib.request
from celery import shared_task

PING = "https://cronpup.com/p/REPORT-UUID"

def ping(suffix=""):
    try:
        urllib.request.urlopen(PING + suffix, timeout=10)
    except Exception:
        pass  # monitoring must never break the task

@shared_task
def nightly_report():
    ping("/start")
    try:
        build_report()
    except Exception:
        ping("/fail")
        raise
    ping()

Match the beat schedule

app.conf.beat_schedule = {
    "nightly-report": {"task": "tasks.nightly_report", "schedule": crontab(hour=2, minute=30)},
}
app.conf.timezone = "UTC"

Create the CronPup monitor with the cron expression 30 2 * * * in UTC, and a grace period that covers queue delay plus run time.

Many periodic tasks?

Use one monitor per important task, so the alert names the task that stopped. A lightweight heartbeat task every 5 minutes also gives you an early warning that beat or the workers are down.

Start monitoring your Celery tasks.