Skip to main content

Cron Monitoring

Dead man's switch for your cron jobs. Get alerted when they stop running.

How It Works

Create a monitor and add a ping to the end of your cron job. Runlater expects periodic pings and alerts you if they stop arriving within the expected window.

  1. Create a monitor with an expected schedule (interval or cron)
  2. Add a ping to your cron job (one cURL command)
  3. Runlater tracks each ping and calculates when the next one is due
  4. If a ping is late (beyond the grace period), you get an alert
  5. When pings resume after downtime, you get a recovery notification

Adding a Ping

Each monitor has a unique ping URL. Add it to the end of your cron job:

Crontab
# Example: nightly backup with ping
0 2 * * * /usr/local/bin/backup.sh && curl -fsS --retry 3 https://runlater.eu/ping/pm_your_token_here
Docker / Kubernetes CronJob
# Run your task, then ping on success
command: ["/bin/sh", "-c", "python manage.py clearsessions && curl -fsS https://runlater.eu/ping/pm_xxx"]
GitHub Actions
steps:
  - name: Run database backup
    run: ./scripts/backup.sh

  - name: Ping Runlater
    run: curl -fsS --retry 3 https://runlater.eu/ping/pm_xxx

The -fsS flags make cURL fail silently on errors but show server errors. --retry 3 retries transient network failures.

Tip: Place the ping after your main command using &&. This way, the ping only fires if the task succeeded.

Signaling Failures

By default, a ping means "everything is OK." But you can also actively report failures by sending a fail ping. This immediately marks the monitor as down and triggers failure notifications — no need to wait for a missed ping.

Query Parameters

Parameter Values Description
status ok (default), fail fail immediately marks the monitor as down and triggers notifications
msg Any string (max 1000 chars) Attached to the ping and included in notification emails and webhooks

Convenience Fail URL

Instead of using ?status=fail, you can append /fail to the ping URL:

# These are equivalent:
curl https://runlater.eu/ping/pm_xxx?status=fail
curl https://runlater.eu/ping/pm_xxx/fail

# With a message:
curl "https://runlater.eu/ping/pm_xxx/fail?msg=Disk+usage+at+95%25"

Practical Example

Report success or failure from a shell script:

Crontab with failure reporting
0 2 * * * /usr/local/bin/backup.sh && curl -fsS https://runlater.eu/ping/pm_xxx || curl -fsS "https://runlater.eu/ping/pm_xxx/fail?msg=Backup+script+failed"
Tip: Use && for the success ping and || for the fail ping. This way your monitor always gets a signal — either "OK" or "something went wrong."

Schedule Types

Fixed Interval

Expect a ping every N seconds. After each ping, the next expected time is calculated as: last_ping + interval.

Available presets: 1 min, 5 min, 15 min, 30 min, 1 hour, 6 hours, 12 hours, 24 hours, 7 days.

Cron Expression

Use a cron expression to match your job's schedule. Runlater calculates the next expected ping time from the cron expression. See the cron syntax docs for expression reference.

Grace Period

The grace period is extra time allowed after the expected ping time before an alert is triggered. This accounts for tasks that take varying amounts of time to complete.

Available options: no grace period, 1 min, 5 min, 15 min, 30 min, 1 hour.

Example: A backup task runs at 2:00 AM and usually takes 5-20 minutes. Set interval to "24 hours" and grace period to "30 minutes". If the ping doesn't arrive by 2:30 AM, you get an alert.

Monitor Statuses

Status Description
New Created but no ping received yet. Waiting for first ping.
Up Pings arriving on schedule. Everything is healthy.
Down Expected ping not received within grace period. Alert sent.
Paused Monitoring disabled. No alerts will be sent.

Notifications

Monitor alerts use your organization's notification settings (email and webhook). Configure them in Organization Settings → Notifications.

  • Down alert: Sent when a monitor misses its expected ping (respects notify_on_failure setting)
  • Recovery alert: Sent when pings resume after downtime (respects notify_on_recovery setting)
  • Per-monitor overrides: Override notification settings for individual monitors without affecting organization-wide settings. Set notify_on_failure and notify_on_recovery from the monitor edit page or via the API.

Notification Webhook Payloads

// Monitor down notification (with optional message from fail ping)
{
  "event": "monitor.down",
  "monitor": {
    "id": "01JJXYZ...",
    "name": "Nightly Backup",
    "status": "down",
    "last_ping_at": "2025-02-06T02:05:00Z",
    "message": "Disk usage at 95%"
  }
}

// Monitor recovery notification
{
  "event": "monitor.recovered",
  "monitor": {
    "id": "01JJXYZ...",
    "name": "Nightly Backup",
    "status": "up",
    "last_ping_at": "2025-02-07T02:03:00Z"
  }
}

Slack and Discord webhook URLs are auto-detected and formatted with appropriate rich messages.

Ping Endpoint

The ping endpoint accepts both GET and POST requests. No authentication needed — the token in the URL is the authentication.

# GET request
curl https://runlater.eu/ping/pm_your_token_here

# POST request
curl -X POST https://runlater.eu/ping/pm_your_token_here

Responses

Status Body Meaning
200 {"status": "ok", "monitor": "..."} Ping recorded successfully
200 {"status": "fail", "monitor": "..."} Failure ping recorded, monitor marked as down
404 {"error": "Monitor not found"} Invalid token
410 {"error": "Monitor is disabled"} Monitor is paused/disabled

Monitors API

Manage monitors programmatically via the REST API. All endpoints require an API key passed as a Bearer token. See the API Reference for authentication details.

List Monitors

curl https://runlater.eu/api/v1/monitors \
  -H "Authorization: Bearer pk_xxx.sk_xxx"

Create Monitor

curl -X POST https://runlater.eu/api/v1/monitors \
  -H "Authorization: Bearer pk_xxx.sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Nightly Backup",
    "schedule_type": "interval",
    "interval_seconds": 86400,
    "grace_period_seconds": 1800
  }'

Get Monitor

curl https://runlater.eu/api/v1/monitors/:id \
  -H "Authorization: Bearer pk_xxx.sk_xxx"

Update Monitor

curl -X PUT https://runlater.eu/api/v1/monitors/:id \
  -H "Authorization: Bearer pk_xxx.sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Updated Name",
    "grace_period_seconds": 3600
  }'

Delete Monitor

curl -X DELETE https://runlater.eu/api/v1/monitors/:id \
  -H "Authorization: Bearer pk_xxx.sk_xxx"

List Pings

curl https://runlater.eu/api/v1/monitors/:id/pings?limit=20 \
  -H "Authorization: Bearer pk_xxx.sk_xxx"

For the full API specification including request/response schemas, visit the interactive API docs.

Tier Limits

Free Pro
Monitors 3 Unlimited
Ping history 30 days 30 days