What is cron monitoring

Cron monitoring tells you when a scheduled job did not run or did not succeed, by having each successful run leave a signal and alerting you when the expected signal is missing.

Cron has no idea whether your job worked. It starts the command at the scheduled minute and moves on. If the script exits 1, the output goes to a local mail spool nobody reads. If the server is rebuilt and the crontab is not, nothing runs and nothing complains. The usual way founders find out is a customer asking why invoices stopped, or a restore that finds the newest backup is 41 days old.

How to monitor cron jobs

  • Push: the job calls a monitor URL after it succeeds, and the monitor alerts when a call is late. Dedicated cron monitoring tools work this way. They take your schedule, add a grace period, and alert at the moment a run should have reported in and did not.
  • Pull: the job leaves evidence, such as a marker file or a row with a timestamp, and an HTTP endpoint returns 503 once that evidence is older than it should be. Any uptime monitor can watch that endpoint.
  • Either way, chain the signal with && so a failed run stays quiet. A cron monitor that hears from a job that crashed is worse than no monitor.

Watching a cron job with an HTTP check

Logdash watches cron jobs the pull way. Its push monitors expect a call in every 15-second window, which suits always-on workers, not a job that runs once an hour. So the hourly job touches a file, and a small endpoint turns the age of that file into a status code.

crontab -e
# Back up every hour. touch only runs when backup.sh exits 0.
0 * * * * /srv/app/bin/backup.sh && touch /var/lib/app/backup.ok
freshness.js
// freshness.js - run next to the job: node freshness.js
const http = require('node:http');
const fs = require('node:fs');

const MARKER = '/var/lib/app/backup.ok';
const MAX_AGE_MS = 2 * 60 * 60 * 1000; // hourly job, alert after 2 hours of silence

http
  .createServer((req, res) => {
    let ageMs = Infinity;
    try {
      ageMs = Date.now() - fs.statSync(MARKER).mtimeMs;
    } catch {
      // no marker yet: the job has never succeeded
    }
    const fresh = ageMs < MAX_AGE_MS;
    res.writeHead(fresh ? 200 : 503, { 'cache-control': 'no-store' });
    res.end(fresh ? 'ok\n' : 'stale\n');
  })
  .listen(8080);

It answers 200 while the last good run is under 2 hours old and 503 after that. Set the limit to one schedule interval plus your longest run, so a single slow night does not page you. If the app already has a health route, add the same file check there instead of running a second server.

Set it up

  1. Expose the check Run freshness.js on the box where the job runs, or fold the check into your existing health route, and make the URL reachable from the internet.
  2. Add an HTTP monitor Create a service in Logdash and give it that URL. Checks run every 5 minutes on the free plan, every minute on Builder and every 15 seconds on Pro, and each one records the status code and response time.
  3. Break the job Make backup.sh exit 1, or backdate the marker with touch -d "3 hours ago". On the next check the endpoint answers 503, the monitor flips to down, and a Telegram alert reaches your phone with the monitor name and the status code.

Cron monitoring tools

Logdash vs Healthchecks.io for cron jobs

FeatureLogdashHealthchecks.io
How a job reportsTouches a file, an HTTP check reads its agePings a URL, with optional start and fail signals
Knows the scheduleNo, you encode it as a maximum agePeriod or cron expression with timezone, plus grace time
Free planFive services, HTTP checks every 5 minutes20 jobs, 100 log entries each
Alert channelsTelegram and webhookEmail, Telegram, Slack, Discord and 20+ more
Uptime checks on the app itselfSame service, same dashboardNot built, it only listens for pings
Self-hostingAGPL-3.0, not a one-command install yetBSD 3-clause, official Docker image

When Healthchecks.io is the better pick

  • Most of what you run is scheduled jobs. A tool that reads the cron expression alerts within the grace time of a missed run, with no endpoint to write.
  • You have 15 jobs across 4 servers. One curl per crontab line beats one freshness check per job.
  • You need to know a run started and never finished. Start and success signals measure duration, and a file timestamp cannot.
  • You want the alert by email. Logdash sends Telegram messages and webhooks only.
Does cron email me when a job fails?
Only if the box can send mail. Cron mails whatever a job prints to the crontab owner, or to the MAILTO address, through the local mail system. Most cloud servers have none, so the output is dropped or sits in a local spool, and a job that fails without printing anything sends nothing at all.
How to monitor cron jobs?
Make every successful run leave a signal, chained with && so a failure leaves none. Then either ping a cron monitor that knows the schedule, or record a timestamp and serve it from an endpoint that returns 503 when it gets too old, watched by an uptime monitor.
How late can a cron monitor alert me?
A schedule-aware tool alerts at the expected run time plus the grace period you set. The HTTP check on this page alerts once the marker passes its maximum age, plus up to one check interval: 5 minutes on the free plan, 1 minute on Builder, 15 seconds on Pro.
What is cron monitoring in Logdash?
An HTTP monitor on an endpoint that reports when the job last succeeded. Logdash push monitors use a 15-second window, so they are a heartbeat for always-on workers, not a schedule-aware cron monitor.

Point it at your own URL and watch it for real.