Runpeek Cron job monitoring

Cron job monitoring tools with a free tier: 7 options compared

Runpeek monitors a cron job from inside the crontab line: tqdml run -- ./backup.sh streams each run's output live, records the exit code and alerts you when it finishes, fails or stalls. For heartbeat pings, Healthchecks.io's free tier covers 20 jobs, Better Stack 10, Cronitor 5, and Dead Man's Snitch and Sentry 1 each, while self-hosted Uptime Kuma has no plan limits.

6 min readLogs and monitoring

At a glance

  • tqdml run -- ./backup.sh in the crontab line gives you each run's live output, exit code and a Runpeek alert when it fails or stalls.
  • Healthchecks.io gives you 20 free jobs, Better Stack 10, Cronitor 5, and Dead Man's Snitch and Sentry 1 each.
  • Chain a curl ping with && to report success only, or send /$? to Healthchecks.io to report the exit code.
  • Uptime Kuma is self-hosted, so run it on a different machine than the jobs it watches.
  • Set PATH, escape % as \% and log the output, or the job can fail before it reports anything.

Free tiers compared

Here is how the seven tools compare on their free limits, checked on each vendor's pricing page on October 30, 2026:

ToolFree tierHostingHow a job reports
RunpeekLive links with no account; a free account adds 7-day history and 3 alert rulesHostedtqdml run -- <command> wraps the job
Healthchecks.io20 jobs, 100 log entries per jobHosted, or self-host the open-source servercurl to hc-ping.com/<uuid>
Better Stack10 monitors and heartbeats, 1 status page, personal projectsHostedcurl to a heartbeat URL
Cronitor5 monitors, email and Slack alertsHostedcurl to cronitor.link with state=
Dead Man's Snitch1 snitchHostedcurl to nosnch.in/<token>
Sentry Crons1 cron monitorHostedsentry-cli monitors run
Uptime KumaNo plan limitsSelf-hostedPush monitor URL

Runpeek watches each run from the inside; the other six are heartbeat monitors that alert you when a scheduled ping is late. Healthchecks.io has the largest hosted free tier among them.

How cron job monitoring works

You can watch a cron job in two ways: wrap the command, or have it send a heartbeat. A wrapper such as Runpeek's tqdml run starts the job itself, so it sees every line of output and the exit code.

A heartbeat, also called a dead man's switch, is an HTTP request your job makes to a unique URL when it finishes. The service expects that ping every period plus a grace period and alerts you when one is missing.

If you chain the ping with &&, the request only fires when the script exits with 0, so a failed run turns into a missing ping once the grace period runs out. Healthchecks.io and Cronitor also take a start signal to measure duration and catch hung jobs, and a fail signal so you hear about a failure right away instead of waiting for the timer.

Bash
0 3 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 --retry 5 -o /dev/null https://hc-ping.com/your-uuid
0 4 * * * curl -fsS -m 10 --retry 5 -o /dev/null https://hc-ping.com/your-uuid/start; /usr/local/bin/report.sh; curl -fsS -m 10 --retry 5 -o /dev/null https://hc-ping.com/your-uuid/$?

The first line only pings if the backup succeeds. The second sends /start before the job and then /$?, which reports the exit code (0 is success, anything else is a failure) the moment the script finishes.

The 7 options

Runpeek

With tqdml run in the crontab line, each run streams its output and tqdm bars to a live link that keeps the last 500 lines (10,000 on Pro) and ends as Finished on exit code 0 or Failed on anything else. A free account keeps runs for 7 days and adds 3 alert rules.

Healthchecks.io

The $0 Hobbyist plan monitors 20 jobs and keeps 100 log entries per job. Jobs ping https://hc-ping.com/<uuid>, and the /start, /fail and /<exit-status> suffixes record run times and failures. SMS and WhatsApp credits start on the $20 Business plan with 100 jobs, and the server is open source (BSD 3-clause) if you'd rather host it yourself.

Better Stack

Better Stack is free for personal projects: 10 monitors and heartbeats, 1 status page, and Slack and email alerts. A heartbeat waits for a request to its secret URL at the frequency you set plus a grace period, and adding /fail to the URL reports a failure right away.

Cronitor

Cronitor's free plan covers 5 monitors with email and Slack alerts but no SMS. Jobs report with curl https://cronitor.link/p/<API_KEY>/<job-name>?state=complete, and state=run and state=fail mark starts and failures. Past 5 monitors you pay $2 per monitor and $5 per user each month.

Dead Man's Snitch

Dead Man's Snitch gives you 1 snitch for free, and the $5 plan has 3. You append && curl https://nosnch.in/<token> to the job, so the check-in only happens when the script exits cleanly. One snitch covers a single backup; a second job means paying.

Sentry Crons

Sentry includes 1 cron monitor on every plan, including the free Developer plan, and charges $0.78 for each extra one on paid plans. Instead of curl, you export your project's SENTRY_DSN and wrap the job with sentry-cli monitors run, which reports missed runs and runs that exceed their maximum runtime.

Bash
export SENTRY_DSN="your-project-dsn"
sentry-cli monitors run --schedule "0 3 * * *" nightly-backup -- /usr/local/bin/backup.sh

Uptime Kuma

Uptime Kuma 2.5.8 (October 26, 2026) is open source and self-hosted, so there are no plan limits. Its Push monitor waits for your job to call a URL, next to HTTP, TCP, ping and DNS checks, and it alerts through Telegram, Discord, Slack, email and 90+ other services.

Bash
docker run -d --restart=always -p 3001:3001 -v uptime-kuma:/app/data --name uptime-kuma louislam/uptime-kuma:2

Keep it on a different machine than your cron jobs: if both share a box that dies, nothing sends the alert.

Cron mistakes that look like monitoring failures

Many silent failures happen before your script or its curl ever runs. Cron runs commands with /bin/sh, sets LOGNAME and HOME, and uses a short PATH (just /usr/bin:/bin on Debian 13), so a command that works in your terminal can fail with "command not found".

  • Cron turns an unescaped % into a newline and sends the rest to the command's stdin, so write date +\%F.
  • Redirect output with >> /path/job.log 2>&1, or set MAILTO to mail it to you (MAILTO="" turns mail off).
  • Wrap the command in flock -n /tmp/job.lock so a slow run makes the next one exit instead of stacking up.
  • On Debian and Ubuntu, journalctl -u cron shows whether cron started the job at all.
Bash
MAILTO=you@example.com
PATH=/usr/local/bin:/usr/bin:/bin

*/5 * * * * flock -n /tmp/sync.lock /opt/jobs/sync.sh >> /var/log/sync-$(date +\%F).log 2>&1

How to choose

  • Each run's live output, exit code and an alert when it fails or stalls: Runpeek, with tqdml run in the crontab line.
  • A hosted heartbeat for a handful of jobs: Healthchecks.io for 20 jobs, or Better Stack for 10 monitors and a status page on a personal project.
  • A team already on Sentry: Sentry Crons, at $0.78 per monitor past the first on a paid plan.
  • No third-party service: Uptime Kuma's Push monitor on a separate machine.

FAQ

Can I monitor cron jobs for free?

Yes. Runpeek streams each run's output and exit code with no account, and a free account adds 3 alert rules. For heartbeat pings, Healthchecks.io monitors 20 jobs for free, Better Stack 10 for personal projects, Cronitor 5, and Dead Man's Snitch and Sentry 1 each. With a spare server, you can self-host Uptime Kuma or the open-source Healthchecks server.

What is the difference between a missed run and a failed run?

A missed run means no ping arrived before the schedule plus grace period ran out, because the server was down, cron stopped or the job hung. A failed run means the job ran and reported an error through a fail signal or a non-zero exit code.

Why does my script work in a terminal but fail in cron?

Cron runs commands with /bin/sh, a short PATH and few environment variables, and it turns any unescaped % into a newline. Use absolute paths or set PATH in the crontab, call bash explicitly if the script needs it, and write \% for percent signs.

Should I self-host a cron monitor?

You don't have to. Runpeek is hosted, so a tqdml run job only needs outbound HTTPS, and a stalled alert rule still fires if the server dies mid-run. Self-hosting Uptime Kuma or Healthchecks makes sense when you have more jobs than the free tiers allow and a second server in another location. Never run the monitor on the same machine as the jobs it watches, because a crash there takes the alerts down too.

Can Runpeek tell me if a cron job never started?

No. Runpeek learns about a run when tqdml run starts it, so a job that never starts, because cron stopped or the server was down, sends nothing. Add a heartbeat ping to Healthchecks.io, Cronitor or Uptime Kuma next to tqdml run to catch that.

Check on long runs from your phone

Change one import and every tqdm bar prints a link you can open on any device. Get a Discord or Slack message when the run finishes, fails or stalls.

Get a live linkpip install tqdm-live

Sources