sysload

package
v0.14.21 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 29, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package sysload is the outpost's considerate system-load profiler. It samples CPU utilization, memory availability, and the load average on a slow cadence (~30s), learns a per-hour-of-day baseline of "normal" load over days, and answers two questions the warm-serving supervisor asks continuously:

  • Busy() — is the machine currently doing meaningful non-LLM work? True when the current load is well above this hour's learned baseline OR above absolute safety thresholds (CPU sustained >60%, or available memory <25%). Debounced so a brief spike doesn't flap the answer.
  • WarmBudgetBytes(usableMem) — how much memory the host is willing to dedicate to keeping LLM models warm. A conservative fraction of usable memory (default 0.33 — leaves ~2/3 for the OS and the user's own apps), and exactly zero while Busy() so the host fully yields to the user's work.

Pure Go, cgo-free, cross-compile clean. Per-platform probes live in sample_{darwin,linux,windows,other}.go behind build tags; each is best-effort and degrades to "unknown" (a negative sentinel) rather than erroring, so a probe that can't run on some host never breaks the profiler — it just leans on whichever signals are available.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Path is where the learned per-hour baseline persists across
	// restarts (typically <cacheDir>/outpost/sysload.json). Empty
	// disables persistence (the baseline is learned fresh each boot).
	Path string

	// Frac is warm_budget_frac — the fraction of usable memory the host
	// will dedicate to warm preload. <=0 or >1 falls back to 0.33.
	Frac float64

	SampleInterval  time.Duration // 0 → 30s
	CPUBusyPct      float64       // 0 → 60
	MinMemAvailFrac float64       // 0 → 0.25
	EnterDelay      time.Duration // 0 → 2m
	ExitDelay       time.Duration // 0 → 5m
	BaselineFactor  float64       // 0 → 1.5

	Logger *slog.Logger
	// contains filtered or unexported fields
}

Config tunes the profiler. Zero values fall back to the package defaults, so `New(Config{})` is a sensible always-on profiler. The operator-facing knob is Frac (warm_budget_frac); the thresholds are exposed for tests and future config surfaces.

type Profiler

type Profiler struct {
	// contains filtered or unexported fields
}

Profiler samples system load, learns the daily baseline, and answers Busy() / WarmBudgetBytes(). Safe for concurrent use: Run() is the single writer; Current()/Busy()/WarmBudgetBytes() read under the mutex.

func New

func New(cfg Config) *Profiler

New builds a Profiler, loading any persisted baseline from cfg.Path.

func (*Profiler) Busy

func (p *Profiler) Busy() bool

Busy reports the current debounced busy verdict.

func (*Profiler) Current

func (p *Profiler) Current() Sample

Current returns the most recent sample. Zero-value At means the profiler hasn't sampled yet.

func (*Profiler) Run

func (p *Profiler) Run(ctx context.Context) error

Run samples immediately, then on every SampleInterval, until ctx is cancelled. Always returns nil (a slow load probe is never fatal).

func (*Profiler) WarmBudgetBytes

func (p *Profiler) WarmBudgetBytes(usableMem uint64) int64

WarmBudgetBytes is the conservative memory the host will dedicate to warm preload: Frac × usableMem, or exactly 0 while Busy() (full yield). usableMem is the host's usable memory in bytes (typically total physical RAM; on unified-memory GPUs that's the shared pool).

func (*Profiler) WarmBudgetFrac

func (p *Profiler) WarmBudgetFrac() float64

WarmBudgetFrac returns the configured warm-budget fraction.

type Sample

type Sample struct {
	At           time.Time `json:"at"`
	CPUPercent   float64   `json:"cpu_percent"`    // effective system CPU %, 0..100; -1 unknown
	MemAvailFrac float64   `json:"mem_avail_frac"` // available/total memory, 0..1; -1 unknown
	Load1        float64   `json:"load1"`          // 1-min load average; -1 unknown
	Busy         bool      `json:"busy"`
}

Sample is one instantaneous reading, plus the debounced Busy verdict in effect after it was folded in. Negative fields mean "this host couldn't measure that signal" (e.g. no load average on Windows).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL