All posts

July 28, 2026 6 min read

Cron job monitoring without Prometheus

Prometheus is powerful, but setting it up for cron job monitoring requires kube-state-metrics, PushGateway, Alertmanager, and ongoing maintenance. Here's a simpler path that requires none of it.


Prometheus is the right tool for a lot of observability problems. Cron job monitoring is not one of them — at least not without significant setup overhead.

The standard Prometheus approach for monitoring cron jobs involves deploying kube-state-metrics (if you're on Kubernetes), configuring a PushGateway so ephemeral jobs can push metrics before they exit, writing PromQL queries to calculate time since last successful run, and configuring Alertmanager rules that fire when that duration exceeds a threshold. Then you maintain all of it as your job schedules change.

This works. It also takes a day to set up, requires ongoing maintenance, and fails along with the cluster it's monitoring.

Here's why a push-based heartbeat model — HTTP pings from your jobs to an external service — is simpler, more reliable, and easier to maintain for most cron job monitoring use cases.


The Prometheus approach and its trade-offs

Monitoring cron jobs with Prometheus typically requires:

kube-state-metrics (Kubernetes only) to expose job and CronJob state as metrics. This requires a deployment in your cluster that has read access to all namespaces.

Prometheus PushGateway for ephemeral jobs that exit before Prometheus can scrape them. Your job pushes a metric to the PushGateway, Prometheus scrapes it later. PushGateway metrics persist until explicitly deleted, which means you need to manage metric lifecycle alongside job lifecycle.

PromQL queries to calculate time since last successful completion:

time() - max(
  kube_job_status_completion_time * on(job_name) group_left()
  (kube_job_status_succeeded == 1)
)

This query breaks when job names have a timestamp suffix (the default in Kubernetes CronJobs), requiring regex matching that's fragile when naming conventions change.

Alertmanager rules that evaluate the PromQL query and fire when the result exceeds a threshold. These need to be calibrated per-job based on the expected schedule.

The total setup is substantial. Each new cron job requires adding PromQL queries and Alertmanager rules. When a job's schedule changes, the alert threshold needs to change too. And because everything lives inside the cluster (or your Prometheus infrastructure), a cluster-level problem can prevent monitoring from alerting at exactly the moment it's most needed.


The push-based alternative

Push-based heartbeat monitoring inverts the model. Instead of your monitoring infrastructure pulling metrics from your jobs, your jobs push a signal to an external service.

The signal is minimal: an HTTP POST to three endpoints per run — start, success, and fail. The external service holds the schedule configuration and fires an alert if the expected pings don't arrive.

MONITOR_ID="your-monitor-id"
API_KEY="$CRONTIFY_API_KEY"
BASE="https://api.crontify.com/api/v1/ping"

curl -fsS -X POST "$BASE/$MONITOR_ID/start" -H "X-API-Key: $API_KEY" || true
your_job_command
STATUS=$?
if [ $STATUS -eq 0 ]; then
  curl -fsS -X POST "$BASE/$MONITOR_ID/success" -H "X-API-Key: $API_KEY" || true
else
  curl -fsS -X POST "$BASE/$MONITOR_ID/fail" -H "X-API-Key: $API_KEY" || true
  exit $STATUS
fi

This is the entire integration. No kube-state-metrics, no PushGateway, no PromQL, no Alertmanager.


What push-based monitoring handles that Prometheus doesn't

Schedule awareness. The external service parses your cron expression and knows when each run is expected. A job scheduled for 2am that doesn't send a start ping by 2:05am triggers an alert. Prometheus computes time-since-last-success, which requires calibrating an alert threshold per job and updating it when schedules change.

Missed runs from infrastructure failure. If your cluster is down or your cron daemon is stopped, no metrics are produced and Prometheus has nothing to scrape. The external monitoring service detects the absent ping regardless of what's happening inside your infrastructure.

Out-of-the-box hung job detection. A start ping with no corresponding success ping within the maximum duration threshold fires an alert automatically. Prometheus can approximate this but requires additional PromQL and careful threshold calibration.

Output metadata rules. Your job reports what it actually did — records processed, files synced, API calls made. The external service evaluates these against rules you define. Prometheus can store custom metrics pushed via PushGateway, but writing PromQL to evaluate "rows_processed was 0 on the last successful run" is significantly more complex.


When Prometheus is the right choice anyway

Push-based heartbeat monitoring is not a replacement for Prometheus across the board. Prometheus is the right choice for:

  • Continuous services — long-running processes that expose metrics for Prometheus to scrape. Heartbeat monitoring is designed for intermittent jobs, not services.
  • Infrastructure metrics — CPU, memory, disk, network. These come naturally from Prometheus exporters.
  • High-cardinality event data — request rates, error rates, latency percentiles. Prometheus is built for this; heartbeat monitoring isn't.
  • Teams already running Prometheus — if you have Prometheus deployed and maintained, adding CronJob monitoring to an existing setup costs less than adopting a separate tool.

The question is whether your existing Prometheus infrastructure is already in place and well-maintained, or whether you're considering deploying it primarily for cron job monitoring. In the latter case, the total operational cost of Prometheus for this specific use case is high relative to a dedicated heartbeat monitoring service.


The hybrid approach

For teams running Prometheus for other reasons, the cleanest approach is to use both:

  • Prometheus for infrastructure metrics, service health, and continuous workload monitoring
  • Push-based heartbeat monitoring for cron jobs specifically

The two systems complement each other. Prometheus doesn't need to handle the schedule-awareness problem. The heartbeat monitor doesn't need to handle infrastructure metrics. Neither system gets stretched beyond what it was designed for.

Crontify is free for up to 5 monitors — no credit card required. Adding heartbeat monitoring for a job running on any infrastructure takes under five minutes regardless of whether you already have Prometheus deployed.


Start monitoring your scheduled jobs

Free plan includes 5 monitors. No credit card required. Up and running in under 5 minutes.

Get started free →