Scheduling and Automation
Let machines handle the repetitive stuff. With cron schedules and heartbeat checks, your AI companions become tireless automation engines.
Cron Basics
What Is Cron?
Cron is the time-based scheduler on Linux and Unix systems. Tell it “when” and “what”, and it runs the command on schedule.
Cron Syntax
┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-6, 0=Sunday)
│ │ │ │ │
│ │ │ │ │
* * * * * command to run
Common Examples
{`# Every day at 8 AM
0 8 * * * /path/to/script.sh
# Every hour
0 * * * * /path/to/script.sh
# Every 15 minutes
*/15 * * * * /path/to/script.sh
# Every Monday at 9 AM
0 9 * * 1 /path/to/script.sh
# 3 AM on the 1st of the month
0 3 1 * * /path/to/script.sh
# Every hour on weekdays
0 * * * 1-5 /path/to/script.sh
# 9 AM, noon, and 6 PM daily
0 9,12,18 * * * /path/to/script.sh`}
Configuring a Cron Job
{`# 1. Edit crontab
crontab -e
# 2. Add your schedule (example: daily DB backup)
0 2 * * * cd /home/node/.openclaw/workspace && ./scripts/backup-db.sh
# 3. View current schedules
crontab -l
# 4. Remove all schedules (use with care)
crontab -r`}
Heartbeat Checks
What Is Heartbeat?
Heartbeat is realvco’s periodic health-check mechanism. Cron runs on a fixed schedule; heartbeat checks state and acts only when necessary.
Heartbeat vs Cron
| Attribute | Cron | Heartbeat |
|---|---|---|
| Execution | Always runs at the scheduled time | Checks state, acts conditionally |
| Fits | Backups, report sending | Monitoring, health checks |
| Flexibility | Fixed time | Adjusts to state |
| Resource use | Constant | Only when something triggers |
Heartbeat Flow
┌─────────────────────────────────────────────────────────┐
│ Heartbeat Loop │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ Start check │ ◄──────────────────────────┐ │
│ └──────┬──────┘ │ │
│ │ │ │
│ ▼ │ │
│ ┌─────────────┐ Healthy ┌─────────┐ │ │
│ │ Check state │ ────────────→│ Log it │ │ │
│ └──────┬──────┘ └────┬────┘ │ │
│ │ │ │ │
│ │ Unhealthy │ │ │
│ ▼ │ │ │
│ ┌─────────────┐ │ │ │
│ │ Run remedy │ │ │ │
│ │ workflow │ │ │ │
│ └──────┬──────┘ │ │ │
│ │ │ │ │
│ ▼ │ │ │
│ ┌─────────────┐ │ │ │
│ │ Notify admin │ │ │ │
│ └─────────────┘ │ │ │
│ │ │ │
│ └─────────────────────────────────┘ │ │
│ Wait for the next tick (~30 min) │ │
│ │ │
└────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────┘
Heartbeat Configuration File
{`# HEARTBEAT.md — Scheduled check list
## System Resources
Frequency: every 2 hours
Tasks:
- [ ] Check disk usage (warn at 80%)
- [ ] Check memory (warn at 90%)
- [ ] Check CPU load
- [ ] Log results
## Service Health
Frequency: every 30 minutes
Tasks:
- [ ] Check Nginx status
- [ ] Check database connectivity
- [ ] Check Docker container state
- [ ] Check SSL certificate expiry
## Project Progress
Frequency: 4 times daily
Tasks:
- [ ] Check for uncommitted git changes
- [ ] Check pending work items
- [ ] Update project progress tracker
## Calendar Reminders
Frequency: every 5 minutes
Tasks:
- [ ] Check upcoming meetings
- [ ] Send reminders
- [ ] Preview tomorrow's schedule`}
Heartbeat State Tracking
{`{
"lastChecks": {
"systemResources": "2026-03-21T08:00:00Z",
"serviceHealth": "2026-03-21T08:30:00Z",
"projectProgress": "2026-03-21T08:00:00Z"
},
"alerts": {
"diskSpace": {
"status": "ok",
"lastAlert": null,
"threshold": 80
},
"memory": {
"status": "warning",
"lastAlert": "2026-03-21T06:00:00Z",
"threshold": 90
}
},
"checkCount": {
"today": 24,
"thisWeek": 168
}
}`}
Common Automation Recipes
1. Database Backup
{`#!/bin/bash
# Daily database backup
BACKUP_DIR="/backup/database"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="myapp"
RETENTION_DAYS=7
mkdir -p "$BACKUP_DIR"
echo "Backing up database..."
mysqldump -u root -p"$DB_PASSWORD" "$DB_NAME" | gzip > "$BACKUP_DIR/db_${DATE}.sql.gz"
if [ $? -eq 0 ]; then
echo "✅ Backup succeeded: db_${DATE}.sql.gz"
# Optional: upload to cloud storage
# aws s3 cp "$BACKUP_DIR/db_${DATE}.sql.gz" s3://my-backup-bucket/
curl -s -X POST "https://api.telegram.org/bot$BOT_TOKEN/sendMessage" \
-d "chat_id=$ADMIN_CHAT_ID" \
-d "text=✅ Database backup complete: db_${DATE}.sql.gz"
else
echo "❌ Backup failed"
curl -s -X POST "https://api.telegram.org/bot$BOT_TOKEN/sendMessage" \
-d "chat_id=$ADMIN_CHAT_ID" \
-d "text=🚨 Database backup failed — check immediately!"
fi
# Prune backups older than 7 days
find "$BACKUP_DIR" -name "db_*.sql.gz" -mtime +$RETENTION_DAYS -delete
echo "Pruned backups older than $RETENTION_DAYS days"`}
2. SSL Certificate Expiry Reminder
{`#!/bin/bash
# SSL expiry check
DOMAIN="example.com"
WARN_DAYS=14
EXPIRY_DATE=$(echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN:443" 2>/dev/null | \
openssl x509 -noout -dates | grep notAfter | cut -d= -f2)
EXPIRY_TIMESTAMP=$(date -d "$EXPIRY_DATE" +%s)
CURRENT_TIMESTAMP=$(date +%s)
DAYS_UNTIL_EXPIRY=$(( (EXPIRY_TIMESTAMP - CURRENT_TIMESTAMP) / 86400 ))
if [ "$DAYS_UNTIL_EXPIRY" -lt "$WARN_DAYS" ]; then
MESSAGE="⚠️ SSL expiry warning\\n\\n"
MESSAGE+="Domain: $DOMAIN\\n"
MESSAGE+="Expires: $EXPIRY_DATE\\n"
MESSAGE+="Days left: $DAYS_UNTIL_EXPIRY\\n\\n"
MESSAGE+="Renew it soon."
curl -s -X POST "https://api.telegram.org/bot$BOT_TOKEN/sendMessage" \
-d "chat_id=$ADMIN_CHAT_ID" \
-d "text=$MESSAGE"
echo "Sent SSL expiry warning"
else
echo "SSL OK — $DAYS_UNTIL_EXPIRY days remaining"
fi`}
3. Website Health Check
{`#!/bin/bash
# Website health check
URLS=(
"https://example.com"
"https://api.example.com/health"
"https://admin.example.com"
)
for URL in "${URLS[@]}"; do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$URL")
RESPONSE_TIME=$(curl -s -o /dev/null -w "%{time_total}" "$URL")
if [ "$STATUS" != "200" ]; then
MESSAGE="🚨 Site anomaly\\n\\n"
MESSAGE+="URL: $URL\\n"
MESSAGE+="Status: $STATUS\\n"
MESSAGE+="Time: $(date '+%Y-%m-%d %H:%M:%S')\\n\\n"
MESSAGE+="Check immediately."
curl -s -X POST "https://api.telegram.org/bot$BOT_TOKEN/sendMessage" \
-d "chat_id=$ADMIN_CHAT_ID" \
-d "text=$MESSAGE"
elif (( $(echo "$RESPONSE_TIME > 5" | bc -l) )); then
MESSAGE="⚠️ Site is slow\\n\\n"
MESSAGE+="URL: $URL\\n"
MESSAGE+="Response time: ${RESPONSE_TIME}s\\n"
MESSAGE+="Check host load"
curl -s -X POST "https://api.telegram.org/bot$BOT_TOKEN/sendMessage" \
-d "chat_id=$ADMIN_CHAT_ID" \
-d "text=$MESSAGE"
else
echo "✅ $URL OK (status: $STATUS, time: ${RESPONSE_TIME}s)"
fi
done`}
Configuration Examples
Full Automation Config
{`# Automation tasks
schedules:
daily_backup:
type: cron
schedule: "0 2 * * *" # every day at 2 AM
script: "scripts/backup-db.sh"
notify_on: [success, failure]
health_check:
type: cron
schedule: "*/30 * * * *" # every 30 minutes
script: "scripts/health-check.sh"
notify_on: [failure]
ssl_check:
type: cron
schedule: "0 9 * * 1" # Monday 9 AM
script: "scripts/check-ssl.sh"
notify_on: [failure]
system_heartbeat:
type: heartbeat
interval: 30m
checks:
- disk_space
- memory
- services
notify_on: [warning, critical]
notifications:
telegram:
bot_token: "${TELEGRAM_BOT_TOKEN}"
chat_id: "${ADMIN_CHAT_ID}"
email:
smtp_server: "${SMTP_SERVER}"
to: "${ADMIN_EMAIL}"
retention:
logs: "30d"
backups: "7d"
reports: "90d"`}
Execution Log
{`[2026-03-21 02:00:00] INFO: starting daily_backup
[2026-03-21 02:00:15] INFO: backup succeeded (size: 150MB)
[2026-03-21 02:00:16] INFO: Telegram notification sent
[2026-03-21 02:00:16] INFO: daily_backup complete
[2026-03-21 08:00:00] INFO: heartbeat check start
[2026-03-21 08:00:01] INFO: Disk space: 45% (OK)
[2026-03-21 08:00:01] INFO: Memory: 62% (OK)
[2026-03-21 08:00:02] INFO: Nginx: running (OK)
[2026-03-21 08:00:02] INFO: Database: connected (OK)
[2026-03-21 08:00:02] INFO: heartbeat check complete
[2026-03-21 08:30:00] INFO: heartbeat check start
[2026-03-21 08:30:01] WARN: Disk space: 82% (WARNING)
[2026-03-21 08:30:01] INFO: warning notification sent
[2026-03-21 08:30:02] INFO: heartbeat check complete`}
Best Practices
1. Error Handling
- Every script has error handling
- Notify on failure
- Log detailed error messages
2. Log Management
- Centralize under a
logs/directory - Rotate old logs periodically
- Keep execution history
3. Notification Strategy
| Task | Notify on Success | Notify on Failure |
|---|---|---|
| Backup | Required | |
| Health check | Required | |
| Report generation | ||
| Routine cleanup |
4. Security
- Store secrets in environment variables
- File permissions:
700for scripts - Audit cron jobs periodically
Summary
Scheduling and automation remove the human from routine tasks:
- Cron: fixed time — backups, reports, cleanup
- Heartbeat: state-based — monitoring, health checks
- Error notifications: hear about problems immediately
- Logging: complete execution history, easy to trace