Cron jobs are the most silently dangerous services in your infrastructure. When a backup job fails, nothing alerts you – until the day you actually need that backup.
Maintenant includes a heartbeat system designed to solve exactly this problem.
The heartbeat principle
The idea is simple: after each successful run, your cron job sends a “ping” to a unique URL. Maintenant knows how often that ping should arrive. If the ping doesn’t come within the expected window, you get alerted.
Configuration in Maintenant
Create a heartbeat monitor via the API:
curl -X POST http://localhost:8080/api/v1/heartbeats \
-H "Content-Type: application/json" \
-d '{
"name": "Backup PostgreSQL",
"interval": "24h",
"grace_period": "1h"
}'
Maintenant returns a unique UUID. Use it in your scripts:
# backup.sh
#!/bin/bash
set -e
# Notify job start
curl -fsS -o /dev/null http://localhost:8080/api/v1/ping/${UUID}/start
# Run the backup
pg_dump -h postgres -U app mydb | gzip > /backups/mydb-$(date +%Y%m%d).sql.gz
# Notify completion with exit code
curl -fsS -o /dev/null http://localhost:8080/api/v1/ping/${UUID}/$?
Start/end signals
The /start signal is optional but powerful. It allows Maintenant to:
- Measure the duration of each run
- Detect jobs that start but never finish (timeout, deadlock)
- Track duration trends over time
Exit codes
By appending /$? to the end of the ping URL, you pass the script’s exit code. A non-zero code is recorded as a failure, even if the ping arrives on time.
Docker integration
For cron jobs running inside Docker containers:
services:
backup:
image: postgres:16
entrypoint: /bin/sh
command: >
-c "pg_dump -h postgres -U app mydb | gzip > /backups/daily.sql.gz &&
wget -qO- http://maintenant:8080/api/v1/ping/YOUR-UUID/$$?"
Best practices
- One heartbeat per critical job – backup, cleanup, certificate renewal, sync
- Generous grace period – if your backup usually takes 5 minutes, set a 30-minute grace period
- Use start/end signals – to detect stuck jobs
- Pass the exit code – a job that “succeeds” with an error code is not a success