[defaults]
[defaults] is the one section in runwisp.toml that doesn’t define
something to run. It defines fallback values that every [tasks.*]
and [services.*] inherits unless they override the field themselves.
It exists because writing the same keep_for = "30d" and
log_max_size = "100mb" on twenty tasks gets tedious. Pull those into
[defaults] once, override per-task only when the value is different.
Available keys
Section titled “Available keys”[defaults]timeout = "1h"log_max_size = "100mb"log_on_full = "drop_old"keep_runs = 50keep_for = "30d"backoff_reset_after = "60s"| Key | Default | What it does |
|---|---|---|
timeout | (unset) | Default per-attempt wall-clock cap. Unset means no timeout. Tasks only — services don’t have a per-attempt timeout. |
log_max_size | 100MB | Default per-run log cap. Units b/kb/mb/gb/tb. Bare 0 and negatives are rejected. |
log_on_full | "drop_old" | Default overflow policy: drop_new, drop_old, kill_task. |
keep_runs | (unset) | Default row-count retention. Positive integer; hard internal cap of 1 000 000. Bare 0 and negatives are rejected. |
keep_for | (unset) | Default age-based retention. Accepts d/w/h/m units. Zero / negative durations are rejected. |
backoff_reset_after | "60s" | A service instance that stays up at least this long resets its restart counter. Services only. Per-service override supported. |
There is no default cron, no default on_overlap, no default
retry_*, no default max_concurrent, no default queue_max, no
default graceful_stop. Those vary per task by intent; defaulting
them would hide behaviour. Per-task graceful_stop falls back to its
built-in default when omitted; set it on each table that needs a
different window.
The daemon-wide [daemon] shutdown_timeout is a separate top-level
setting — it bounds the whole-daemon shutdown
phase. Each task/service still gets its own graceful_stop window
inside that cap. If a graceful_stop exceeds [daemon] shutdown_timeout
the daemon emits a boot-time warning naming the task.
Precedence
Section titled “Precedence”For each task or service:
- If the field is set on the
[tasks.*]/[services.*]table, use that. - Else if it’s set in
[defaults], use that. - Else fall back to the built-in default (e.g.
100MBforlog_max_size).
Omitting a numeric retention field at every level means no cap —
runs accumulate until you set a value somewhere. Bare 0, negative
values, and out-of-range strings are rejected at config load, so
“forgot to cap” never silently means “deleted everything.”
Worked example
Section titled “Worked example”[defaults]timeout = "30m" # most tasks should die after 30 minuteslog_max_size = "50mb" # smaller default, override for noisy taskskeep_runs = 100keep_for = "30d"backoff_reset_after = "30s" # services that stabilise in 30s reset
[tasks.heartbeat]cron = "*/5 * * * *"run = "/usr/local/bin/heartbeat"# inherits 30m timeout, 50mb log cap, 100 runs, 30d retention
[tasks.nightly-export]cron = "0 2 * * *"timeout = "4h" # overrides default — exports take longerlog_max_size = "500mb" # overrides default — output is largegraceful_stop = "20s" # this one needs more than the built-in 5srun = "/usr/local/bin/export"
[services.flaky-worker]backoff_reset_after = "2m" # overrides default — this one takes longer to stabiliserun = "/usr/local/bin/worker"What [defaults] doesn’t do
Section titled “What [defaults] doesn’t do”- It doesn’t apply to
[storage]— that’s a global cap, not a per-task default. - It doesn’t apply to
[notify]settings (coalesce_window,queue_size, etc.). - It doesn’t apply to
[daemon] shutdown_timeout— that’s a daemon-wide setting, not a per-task value to inherit. - Notification routing (
notify_on_failure,notify_on_success) has no defaulting layer — you set it per task.
Where to next
Section titled “Where to next”[tasks.*]reference — the per-task overrides this defaults.[services.*]reference — same.[storage]reference — the daemon-wide disk safeguards (separate from per-tasklog_max_size).