Cron job monitoring
Cron is equally silent when a job finished and when it never started. This guide takes you from a crontab line to an alert in Telegram, in one sitting.
How it works
We do not connect to your server and do not ask for credentials. The job reports for itself — a plain HTTP request to its own unique address. That signal is called a heartbeat.
The rest is arithmetic on our side: if the ping does not arrive in time, the check turns late, then down, and the alert goes out. Which means you hear not only about a job that crashed, but about one that never ran: a broken cron, a full disk, a machine that never came back up.
Step 1. Create a check
In the dashboard, hit New check. There is not much to fill in:
- Schedule — how often the job must ping: a period in seconds, a cron expression or a systemd OnCalendar expression. Syntax and common mistakes are in the cron cheat sheet;
- Time zone — the one the cron expression is read in; daylight saving transitions are handled for you;
- Grace period — slack after the deadline. Cron rarely fires to the second and a backup can run longer than usual: grace keeps schedule jitter from being reported as an outage;
- Tags — used later to filter checks and to route alerts.
Grace can be anything from 0 to 30 days. A good starting point is roughly twice the job's usual runtime — then one slow run will not raise a false alarm.
Step 2. Add one line to your crontab
Once saved, the check shows its ping URL. Append a
curl call to your cron line —
after the job itself and behind
&&, so the signal only
goes out on success:
30 2 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 --retry 3 -o /dev/null https://ping.cronalive.com/<uuid>
Every flag there earns its place:
-f— do not treat 4xx/5xx as success (otherwise curl exits 0 on any response);-s -S— stay quiet normally but print the error if there was one: otherwise cron emails you a progress bar;-m 10— a hard cap on the whole request. Without it a hung socket holds the cron job for as long as it likes;--retry 3— three retries on a network error, with a growing pause;-o /dev/null— the response body is of no use.
More on timeouts, backgrounding and what happens when the service is unreachable: Ping reliability. Ready-made code for bash, Python, Node, PHP, Laravel, systemd and GitHub Actions is on the Snippets page.
Step 3. Verify the first ping
Do not wait for the night — run the line by hand. The check moves from new to up, and its page starts showing the last ping, the next deadline and a log entry.
curl -fsS -m 10 -o /dev/null https://ping.cronalive.com/<uuid>
If the ping does not show up: check that the crontab line
uses an absolute path to curl
(cron has a different PATH) and
that any % is escaped — in a
crontab it means a newline.
Step 4. Wire up alerts
A check with no channel is useless: it will dutifully turn red on a dashboard you are not looking at. The check card shows where its alerts would go; channels are configured under Integrations.
- Telegram — DM or group, linked by a one-time link;
- Slack, Discord, Mattermost — incoming webhook;
- Email, SMS, PagerDuty — on-call and escalation;
- Webhooks — your own handler with signature verification.
What happens when a job fails
The deadline passes, the check turns late, and once grace runs out — down. The transition lands in the event feed with its reason:
At the same moment the alert goes out to every matching integration. Delivery is visible in the journal: status, number of attempts and the failure reason if a channel did not answer.
While the check stays down, reminders arrive at the intervals you configured. The first successful ping brings it back to up and sends a recovery notification.
Next
- Snippets — ready-made code for bash, Python, Node, PHP, Laravel, systemd and GitHub Actions;
- /start, /fail and duration — measuring runtime and reporting a failure immediately;
- Ping reliability — timeouts, retries, limits and fallback domains;
- Cron cheat sheet — syntax, patterns and common mistakes, with a tester for checking when an expression actually fires;
- Laravel scheduler — one macro per task, with the schedule taken from your code instead of retyped here;
- Statuses and lifecycle — where late, down and flap damping come from;
- HTTP checks — when you would rather have us poll a URL than wait for a ping.