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, Telegram, Slack, Discord, or webhook. Free, no monitor cap, no agent to install.

# 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>

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. 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, Telegram, Slack, Discord, or webhook. Add || curl …/fail 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 exits non-zero on an HTTP error instead of pretending success; -sS silences the progress bar (so cron doesn't mail you noise) while keeping real errors; -m 10 caps the request at 10 seconds; 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 the retry means no ping is lost.

  • Do I need an agent or a library?

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

  • Is this free?

    Yes. LastPing is free and fully hosted with no monitor cap and no paid tier — 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 · FULLY HOSTED · NO PAID TIER

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.