Monitor Celery beat tasks: task_success and task_failure signals with LastPing
Connect Celery's built-in task_success and
task_failure signals to ping LastPing on success and POST
to /fail on failure. Filter by sender to
scope each signal to a specific task. Alternatively, use a
@monitored decorator for self-contained task
instrumentation. Absence detection covers a down beat process.
Free, no monitor cap.
The snippets
Create a monitor in the console, set the schedule to match your beat schedule plus a grace window, and copy the ping URL.
Signals — per-task scope with sender=
Connect the signals in your tasks module after defining the task.
Filtering by sender ensures only the monitored task
triggers the ping:
Decorator approach — self-contained per task
A @monitored decorator wraps the task body directly.
Cleaner when you want the ping URL co-located with the task
definition rather than in separate signal handlers:
Retry guard — ping /fail only on final failure
By default, task_failure fires on each failed attempt
including retries. To ping /fail only when retries
are exhausted, check sender.request.retries against
sender.max_retries:
What celery beat going down looks like
If the beat process stops, no tasks are scheduled. No signal fires, no ping is sent. Absence detection is the correct safety net: the missing ping opens an incident after the grace window regardless of why the task didn't run. See also the Airflow guide for a comparison with DAG-level callbacks, the Python guide for script-level monitoring, and the LastPing MCP server for AI-agent provisioning.
What this catches
The signals report what they can; the silence reports the rest.
- Task exception —
task_failurefires and POSTs the exception class and message to/fail, opening an incident immediately. - Task success —
task_successfires and GETs the success ping, resetting the absence timer. - celery beat is down — no task is scheduled, no signal fires; the missing ping opens the incident after the grace window.
- Worker process killed — the in-flight task is lost; no success ping arrives; the absence opens the incident.
- Recovery — the next successful task run fires
task_success, closing the incident automatically.
Questions people ask
Front-loaded answers — the most important fact first.
-
Does task_failure fire on every retry?
Yes, by default. To ping
/failonly on final failure, checksender.request.retries >= sender.max_retriesinside the handler before posting. Alternatively, useafter_returnon the task and check thestateargument forFAILURE. -
What if celery beat is down?
A down beat process never enqueues tasks. No signal fires, no ping is sent. Absence-detection monitoring catches this: the missing ping after the grace window opens an incident — no signal handler code required.
-
Signals vs. decorator — which is better?
Signals are better when you want a single place to configure monitoring for multiple tasks. The decorator is better when you want the ping URL co-located with the task and don't want global signal handlers. Both work; choose based on your team's conventions.
-
Is this free?
Yes. LastPing is free and fully hosted with no monitor cap and no paid tier. See how it compares to Healthchecks.io and Cronitor.
A down celery beat fires no signal. Absence detection does.
Two signal handlers now beat a silent task queue later. First alert wired up in about a minute — and LastPing monitors itself the same way.