Beyond Timing: Catch Silent Successes with Semantic Ping Payloads
The silent success problem
Heartbeat monitoring catches timing failures: a job that stops running, runs late, or crashes before sending a ping. But there's a second failure mode that timing alone can't detect — a job that completes on schedule and exits cleanly, but produces wrong output.
Your nightly backup processed zero records. Your invoice job ran but sent no emails. Your data sync finished in 200 ms instead of 40 seconds because it silently skipped every row. The ping arrived. The monitor stayed green. Nobody got an alert.
Semantic ping payloads close this gap. Instead of just pinging Cronaman to say "I ran", your job sends structured data about what it did. Cronaman evaluates that data against rules you define and fires an alert if anything looks wrong — even when the job itself reported success.
Semantic payloads and assertions are a Pro feature. Free plan users can still send payloads — the ping will be accepted — but the payload is silently dropped and no assertions are evaluated. Upgrade to Pro to unlock full payload storage and assertion-based alerting.
How payload pings work
The ping endpoint accepts an optional JSON body on any POST request. You can include any numeric metrics that are meaningful to your job — records processed, rows inserted, files uploaded, duration in seconds, anything you want to assert on later.
The payload is stored with each ping run and visible in the ping history table on your monitor detail page. Assertion rules are evaluated immediately on receipt — if any rule fails, an alert fires on all configured channels within seconds.
Payload size is capped at 10 KB per ping. Payloads exceeding this limit are rejected with a 413 response.
Sending a payload with curl
Add -X POST and a JSON body to your existing ping command. The endpoint and slug stay the same:
# Simple ping (no payload)
curl -sS https://cronaman.dev/ping/my-backup
# Payload ping (Pro)
curl -sS -X POST https://cronaman.dev/ping/my-backup \
-H "Content-Type: application/json" \
-d '{"records_processed": 1500, "duration_s": 42}'Sending a payload with Python
Use urllib.request from the standard library — no extra dependencies required:
import json
import urllib.request
PING_URL = "https://cronaman.dev/ping/my-backup"
def run_backup():
# ... your job logic here ...
return {"records_processed": 1500, "duration_s": 42}
try:
metrics = run_backup()
data = json.dumps(metrics).encode()
req = urllib.request.Request(
PING_URL,
data=data,
headers={"Content-Type": "application/json"},
)
urllib.request.urlopen(req, timeout=10)
except Exception as e:
print("Job failed:", str(e))
raiseIf your project already uses requests, the pattern is even shorter:
import requests
PING_URL = "https://cronaman.dev/ping/my-backup"
try:
metrics = run_backup()
requests.post(PING_URL, json=metrics, timeout=10)
except Exception as e:
print("Job failed:", str(e))
raiseSending a payload with Node.js
const PING_URL = "https://cronaman.dev/ping/my-backup";
async function runBackup() {
// ... your job logic here ...
return { records_processed: 1500, duration_s: 42 };
}
try {
const metrics = await runBackup();
await fetch(PING_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(metrics),
signal: AbortSignal.timeout(10_000),
});
} catch (err) {
console.error("Job failed:", err);
process.exit(1);
}Defining assertions
Assertions are rules that Cronaman evaluates against the payload on every successful ping. Each rule targets one key in the payload JSON and compares its value to a numeric threshold using an operator.
Available operators:
gt— greater thangte— greater than or equallt— less thanlte— less than or equaleq— equal to
To add an assertion, open your monitor in the Cronaman dashboard and scroll to the Assertions section. Add a rule such as:
- Key:
records_processed/ Operator:gt/ Threshold:0/ Message: "Backup produced no records" - Key:
duration_s/ Operator:lte/ Threshold:300/ Message: "Backup took longer than 5 minutes"
Multiple assertions can be active at once. All are evaluated on every ping; any failure triggers an immediate alert.
What happens when an assertion fails
When a ping payload violates one or more assertions, Cronaman fires an alert on all configured channels — email, Slack, or custom webhook — with the specific failure reason included in the message body. No waiting for a deadline; the alert fires within seconds of the ping arriving.
In the ping history table, assertion-failed rows are highlighted in amber. Clicking the payload icon expands the full JSON so you can inspect the exact values that were sent.
Note that an assertion failure does not change the monitor's timing status. If the ping arrived on time, the monitor stays "healthy" from a timing perspective — but the assertion failure is recorded and alerted separately. Both failure modes are tracked independently.
More cron monitoring guides
New to Cronaman? Start with the language-specific integration guides:
- How to Monitor Cron Jobs in Python — urllib, requests, and crontab setup
- How to Monitor Cron Jobs in Node.js — native fetch, Axios, and node-cron
- How to Monitor Cron Jobs in PHP — file_get_contents, cURL, and Laravel schedulers
Start monitoring your Pro cron jobs
Free forever for up to 3 monitors. No credit card required. Set up in under 2 minutes.
Start monitoring free