Written down mostly so I stop re-deciding the same things.
Off cron, onto a systemd timer
August 2026
The checks used to run from cron. They now run from a systemd timer, for one reason: when a
cron job fails, nothing remembers. A timer gives me a unit that shows up in
systemctl is-failed, which means a failure is a state I can query rather than a line
I have to go find in a log.
This is not hypothetical. Something else on this box had been failing twice a day for a month
behind a perfectly healthy-looking timer, and I only found it by reading a log for an unrelated
reason. Silent recurring failure is the worst kind, because every individual symptom is "nothing
happened".
curl -w is enough
May 2026
I spent an evening looking at proper monitoring agents before noticing that everything I
actually wanted was already a format string:
-w '%{http_code} %{time_total}'
Status code and wall-clock time, from a binary that is already installed and already handles
redirects, TLS and timeouts correctly. The rest of an agent is scheduling, storage and alerting
— and I wanted none of the three. If I ever need connect time and TLS handshake time
separately, %{time_connect} and %{time_appconnect} are right there.
Ten seconds, and why not thirty
April 2026
The timeout is ten seconds. Thirty would catch a few more slow-but-alive responses, but a
target that needs half a minute is not meaningfully up for anything I care about, and a long
timeout makes a run of failures take long enough to overlap the next run. Ten keeps a full pass
well under the interval even if everything on the list is broken at once.
The counters are cumulative, not windowed, so a bad afternoon stays visible in the numbers for
a long time afterwards. That is deliberate — a rolling window quietly forgives whatever fell
outside it.