Configuration
All runtime configuration lives behind the Settings page (/settings). It is
a key-value store that holds strings and returns typed values with a safe
fallback, so a bad value never crashes a queue. Every key ships with a default.
Schedule
Scheduling is data, not config keys: each schedule row owns its own escalation. The scheduler is a thin per-minute dispatcher that enqueues a speed-test job according to the configured cron. Edit the cron expression to change how often tests run.
Servers
- Preferred servers — pin tests to specific Ookla servers.
- Blocked servers — exclude servers from selection.
Both accept server-id lists and are resolved through a single reader.
Retention
Set how long measurements are kept. The CleanupWorker prunes old rows on a
schedule according to the retention policy.
Degradation thresholds
Define what counts as “healthy.” Thresholds resolve as
per-row override → global Settings fallback, with one reader
(thresholds_for/1) so there is a single source of truth and resolution never
yields nil. Register the global default in Settings.@default_settings.
Notification channels
Notifications are behaviour implementations, not branches in a worker. The worker orchestrates; the channel behaviour does the work. Add a new channel by implementing the behaviour.
Ping target
A schedule may override the ping target per row; otherwise it falls back to the global setting:
schedule.target_host || Settings.get("ping_target")