Skip to content
LastPing
GUIDE · CRON · FREE

Monitor a cron job with one line of curl

Append one ping to your crontab line. When the job succeeds, the ping arrives; when it fails, hangs, or never runs at all, the ping doesn't, and LastPing opens an incident and alerts you by email, Slack, Discord, Telegram, ntfy, Pushover, Microsoft Teams, Google Chat or webhook. Free, no monitor cap, no agent to install.

Your assistant can do this for you

Monitor my cron jobs with LastPing

# crontab -e — the whole integration:
0 3 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 --retry 3 -o /dev/null https://ping.lastping.dev/<your-monitor-id>
On this page
  1. Cron fails silently. That's its default.
  2. Setup: one crontab edit, about a minute
  3. What this catches
  4. Questions people ask

Cron fails silently. That's its default.

The classic failure isn't a loud crash: it's a nightly job that quietly stopped weeks ago, discovered the day you actually need it.

Failure mode 01

Errors go to a mail spool nobody reads

Cron's built-in error reporting is local mail via MAILTO. On most servers that's a spool file no human has ever opened.

Failure mode 02

The job that never runs

Server rebuilt without the crontab, cron daemon stopped, a typo'd schedule, an expired credential in the environment: the job doesn't fail, it simply doesn't happen. Nothing can self-report its own absence.

Failure mode 03

The hung job

A job stuck on a lock, a full disk, or a dead network mount never exits, so it never errors. Without overrun detection, a hung job looks exactly like a healthy one.

Dead-man's-switch monitoring inverts the problem: instead of hoping a broken job reports itself, LastPing expects a signal on your schedule, and alerts on the absence. A job that can't run can't hide.

Setup: one crontab edit, about a minute

No agent, no library, no config file: a unique ping URL and one curl.

Create a heartbeat monitor

In the console, create a monitor and give it the job's schedule (a simple interval ("every day") or the exact cron expression with an IANA timezone) plus a grace window (how long past the deadline is still OK). Copy the ping URL:

https://ping.lastping.dev/<your-monitor-id>

Append the ping to the crontab line

&& makes the ping conditional on success: if the job exits non-zero, the ping is skipped and the silence raises the alert:

# m h dom mon dow  command
0 3 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 --retry 3 -o /dev/null https://ping.lastping.dev/<your-monitor-id>

Optional: alert immediately on failure

Waiting out the grace window is fine for most jobs. To be paged the moment the job fails, report the failure explicitly with the /fail endpoint:

# one line — crontab entries can't be split across lines
0 3 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 --retry 3 -o /dev/null https://ping.lastping.dev/<your-monitor-id> || curl -fsS -m 10 --retry 3 -o /dev/null https://ping.lastping.dev/<your-monitor-id>/fail

Optional: catch hung jobs with a wrapper

A /start ping arms overrun detection: if the matching success doesn't arrive within the grace window, LastPing opens an incident even though the job is technically still "running". The /<exit-code> endpoint maps 0 to success and anything else to failure, so one wrapper covers every job:

#!/bin/sh
# /usr/local/bin/lastping-run.sh — wrap any command with start + exit-code reporting
URL="https://ping.lastping.dev/<your-monitor-id>"

curl -fsS -m 10 --retry 3 -o /dev/null "$URL/start"

"$@"
rc=$?

# /0 reports success; any other exit code reports failure
curl -fsS -m 10 --retry 3 -o /dev/null "$URL/$rc"
exit $rc
# crontab -e
0 3 * * * /usr/local/bin/lastping-run.sh /usr/local/bin/backup.sh

Why those flags? -f exits non-zero on an HTTP error instead of pretending success; -sS silences the progress noise but keeps real errors; -m 10 caps the request at 10 seconds so a network blip can't hang your job; and --retry 3 matters because LastPing's ingest is fail-closed: if its queue is briefly unavailable it answers 503 rather than a false 200, and curl re-sends. No ping silently lost, in either direction.

What this catches

Detection runs on durable deadlines in the database: a crash, restart, or deploy never misses a due monitor.

  • The job failed: with && the success ping is skipped and the grace window raises the alert; with /fail you're alerted immediately.
  • The job never ran: crontab lost, cron stopped, machine down. No signal in the expected window → incident.
  • The job hung: a /start ping with no completion inside grace opens an incident while the job is still wedged.
  • Recovery: the next successful ping closes the incident and sends a recovery notice automatically. No manual reset.
  • Flap protection: a job that fails once and recovers within the damping window doesn't page you.

Same pattern, different runner? See the guides for systemd timers, Kubernetes CronJobs, backup scripts, and in-code pings from Python or Node.js, or the full guide index.

Questions people ask

Front-loaded answers: the most important fact first.

  • How do I get notified when a cron job fails?

    Append a ping to the crontab line with && so it only fires on success: 0 3 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 --retry 3 -o /dev/null https://ping.lastping.dev/<your-monitor-id>. If the job fails, the ping never happens, the expected signal doesn't arrive inside the grace window, and LastPing opens an incident and alerts you by email, Slack, Discord, Telegram, ntfy, Pushover, Microsoft Teams, Google Chat or webhook. Add || curl …/fail after it to be alerted immediately instead of waiting out the grace window.

  • How do I know if my cron job didn't run at all?

    A job that never runs can't self-report: that's exactly what dead-man's-switch monitoring solves. LastPing expects the ping on your schedule (a simple interval or a cron expression with an IANA timezone) plus a grace window. If the machine is down, the crontab was lost, or cron itself stopped, no ping arrives and an incident opens automatically.

  • What does curl -fsS -m 10 --retry 3 do?

    -f makes curl exit non-zero on an HTTP error instead of pretending success; -s silences the progress bar (so cron doesn't mail you noise) while -S still prints real errors; -m 10 caps the request at 10 seconds so a network problem can't hang your job; and --retry 3 re-sends on transient failures: LastPing's ingest deliberately answers 503 instead of a false 200 if its queue is briefly unavailable, so curl re-sends and no ping is lost.

  • Do I need to install an agent or library to monitor cron jobs?

    No. A ping is a plain HTTP request (GET, HEAD, or POST all work) to your monitor's unique URL, like https://ping.lastping.dev/<your-monitor-id>. curl, wget, or any HTTP client in any language works. Appending /fail signals an explicit failure, /start signals the beginning of a run and arms overrun detection, and /<exit-code> maps 0 to success and anything else to failure.

  • Is cron job monitoring free?

    Yes. LastPing is free for individuals with no monitor cap, unlike Healthchecks.io's 20-check free plan or Cronitor's 5-monitor free plan. See how LastPing compares to Healthchecks.io and Cronitor.

FREE FOR INDIVIDUALS · FULLY HOSTED

Your quietest cron job is the one to worry about.

One crontab edit now beats an empty backup bucket later. First alert wired up in about a minute, and LastPing monitors itself the same way.