Ping reliability
Monitoring has to be more dependable than the thing it monitors. In practice that comes down to one rule: a ping must never delay your job, and never break it.
Timeouts are mandatory
curl has no overall time limit by
default. Hung sockets are not exotic — dropped packets, a
black-hole firewall, DNS that never answers — and without a
timeout the cron job hangs until something kills it.
curl -fsS -m 10 --connect-timeout 5 --retry 3 -o /dev/null https://ping.cronalive.com/<uuid>
| Flag | What it does |
|---|---|
-m 10 | hard cap on the whole request, retries included |
--connect-timeout 5 | separate cap on establishing the connection |
--retry 3 | retry on a network error and on 5xx, doubling the pause |
--retry-connrefused | treat connection refused as retriable (it is not by default) |
-f | non-zero exit on 4xx/5xx — otherwise curl is happy with any response |
-s -S | no progress bar but keep the error text: otherwise cron emails you on every run |
For scale: a ping is a few hundred bytes. Ten seconds for the whole request is generous, while 30 or more is already comparable to the interval of a frequent job.
Do not background a ping without a timeout
The temptation is obvious: append &
and never wait for the network. Do not:
- a backgrounded
curlwithout-mlives indefinitely. A job that runs every minute leaves you thousands of stuck processes in a day; - cron considers a job finished when all of its processes are gone: a backgrounded ping can keep the entry alive;
- the exit code of a background process is lost — you will never learn that the pings stopped arriving.
If you do need to background it — say, a ping from an interactive script — the timeout is not optional:
# fine curl -fsS -m 10 -o /dev/null "$PING" & # not fine: this process may never exit curl "$PING" &
A ping must not break the job
Monitoring being unreachable is no reason to abort a backup.
Swallow the error explicitly, especially under
set -e:
signal() { curl -fsS -m 10 --retry 3 -o /dev/null "$PING$1" || true; } The Python, Node and PHP snippets do the same with a caught exception. Our SDKs behave this way out of the box: the signal either goes out fast or is quietly dropped.
What if a signal never arrives
Nothing dramatic — and that is a deliberate design, not a concession. A lost ping does not need catching up:
- the next run sends a fresh ping and brings the check back to up;
- if the job genuinely did not run, the check goes down — so you never get a false "all good";
- the only real risk is a false alert caused by a network incident on your side. That is what
--retryplus a sensible grace period are for.
Retrying a signal in a loop inside the job is pointless: it doubles the delay and adds no information.
More than one ping domain
Ping intake lives on several domains and is deployed independently of the dashboard. The current list comes from an open endpoint:
curl -s https://app.cronalive.com/api/v1/ping-domains
The dashboard snippets already carry the fallback behind
|| — the second attempt only
happens if the first one failed:
curl -fsS -m 10 https://ping.cronalive.com/<uuid> || curl -fsS -m 10 https://ping2.cronalive.com/<uuid>
The SDKs read that list themselves. It may grow — do not hardcode it in your own scripts.
Rate limits
Pings are rate limited, but in a way that can never break a heartbeat client:
- ≤ 5 pings per second per check — anything above is dropped;
- ≤ 100 requests per second per IP — same;
- daily ping quotas come with the plan.
The important detail: a dropped ping is answered with
200 OK, not 429. That is on purpose. A client running
with -f must not read this as an
error and must not start retrying — otherwise the limit would
trigger a storm of retries exactly when the system is already
under load. Such a ping is simply not recorded and does not
change the check status.
Practical takeaway: if a job pings more than five times a second, that is almost certainly a loop in a script rather than a requirement. Monitor the run, not every iteration.
See also
- Snippets — ready-made code with all the flags;
- /start, /fail and duration;
- Statuses and lifecycle — grace, flap damping;
- API Reference — including
GET /api/v1/ping-domains.