13 min read #homelab
On this page

Scheduled Tasks and Automated Scheduling

All custom scheduled tasks use systemd timers exclusively, avoiding cron. Advantages over cron include: unified log retrieval via journald, dependency chains (After/Wants), random delays to prevent thundering herd, failure retry mechanisms, and a global overview via systemctl list-timers. This document is grouped by frequency: high-frequency (second-level collection and self-healing) → daily (sync and collection) → monthly (certificates) → daemon-type (long-cycle health checks).

1. High-Frequency (≤5 minutes): Second-Level Collection and Self-Healing

These timers are responsible for real-time metric collection and automatic fault recovery. Output goes to the node_exporter textfile collector → Prometheus. If they fail, monitoring data is lost or network connectivity is broken.

amdgpu-metrics (every 10s)

Collects GPU temperature, power consumption, and frequency.

[Timer]
OnBootSec=15s
OnUnitActiveSec=10s

net-metrics (every 15s)

Collects WiFi signal strength/link quality + proxy latency probes.

rathole-probe (every 30s)

Performs TCP/TLS/HTTP health checks on all services exposed via rathole, outputting the rathole_service_up gauge. This metric drives Grafana's rathole alerting rules (see monitoring.md).

Health check targets:
  TCP: Transit VPS :2333 (rathole control channel)
  HTTPS: derp / grafana / chat / doc / paste / caldav / owntracks
→ rathole_service_up{service="doc"} 1/0

owntracks-collector (every 30s)

Pulls family members' GPS locations, battery levels, and accuracy from the local OwnTracks Recorder API → textfile collector.

wifi-watchdog (every 30s)

Pings gateway .1. Implements layered self-healing for consecutive failures: reconnect → RF reset → driver reload. See network-recovery.md for details.

[Timer]
OnBootSec=60s
OnUnitActiveSec=30s

llama-gpu-sync (every 15s)

Switches power profiles based on actual GPU load: busy≥50% → COMPUTE (profile 5), idle>90s → BOOTUP_DEFAULT (profile 0). User-level timer. See local-llm.md for details.

# ~/.config/systemd/user/llama-gpu-sync.timer
[Timer]
OnBootSec=15s
OnUnitActiveSec=15s

2. Daily: Sync and Collection

Executed during off-peak hours to avoid competing for CPU/network/N100 write resources.

sync-subscribe (03:30)

True source mihomo config → de-hostname sanitization → rsync to transit VPS, outputting clash.yaml + sub.txt (v2rayN base64) for mobile roaming import.

sync-mihomo-to-router (03:45)

Extracts true source proxies/groups/rules into three segments → N100 Nikki profile, with dual-end validation + backup + automatic rollback on failure. Staggered 15 minutes from subscription sync to avoid simultaneous writes to N100.

See network-architecture.md for configuration derivation pipeline details.

backup-system (04:00, random delay 10min)

Incremental rsync of system disk to tank/backup/system + ZFS snapshots, retaining 30 versions. Idle IO priority, Persistent=true for missed runs. See system-backup.md for details.

eix-sync (06:31)

Gentoo eix database sync. Standard system timer, included with Portage installation.

sgcc-collector (08:00, random delay 10min)

Collects State Grid electricity data → textfile collector → Prometheus. Environment variables in /etc/default/sgcc-collector.

llm-job@daily-harvest (23:50)

At night, uses a local model to map-reduce and extract "actual completed work" from that day's Claude Code sessions + openclaw memories, idempotently adding to ~/doc/daily/. Addresses the systemic issue of "tasks completed but not recorded by doc-daily-log". Part of the llm-jobs framework.

llm-job@daily-report (09:00)

Daily summary (weather, work log summary, city) pushed to WeChat. Reads yesterday's ~/doc/daily/ (already populated by daily-harvest), deduplicates and groups into human-readable text via local model before delivery; falls back to original grouping if the model is unavailable. City read from ~/.current-city (maintained by iOS Shortcuts/openclaw). Part of the llm-jobs framework, template unit llm-job@.service. Replaces the old daily-report-weixin.timer (deprecated, script retained as fallback).

3. Monthly

acme-renew (20th of each month at 03:00)

acme.sh DNS-01 (AliDNS) automatic renewal of *.liz6.com wildcard certificates, deployed to the DERP server. Uses proxy 127.0.0.1:7890 (ACME requests require international connectivity).

4. Daemon-Type: Long-Cycle Health Checks

rathole-watchdog (every 5min)

Checks doc tunnel health endpoints. On 3 consecutive failures, executes docker restart rathole-client, with jitter prevention to avoid false positives. See rathole-tunnel.md for details.

# ~/.config/systemd/user/rathole-watchdog.timer
[Timer]
OnBootSec=2min
OnUnitActiveSec=5min

5. Standard System Tasks (cron)

Only system-provided tasks exist; no custom cron tasks:

TaskPathFrequency
man-db/etc/cron.daily/Daily
smartmontools-update-drivedb/etc/cron.monthly/Monthly