The fast, modular Linux system-monitoring dashboard.
Watch CPU, memory, multi-GPU, storage, network, and sensors — live, in one place.
Rust core · Qt 6 / Kirigami UI · CLI + GUI · runtime .so plugins · mTLS remote · no telemetry · GPL-3.0-only.
Overview: live CPU, memory, temperature, and frequency at a glance.
LinSight answers the everyday "what is my machine doing right now?" question. It samples your hardware and kernel and shows it back to you live — as tiles you can rearrange, a scriptable CLI, or a Prometheus feed.
It is built around three goals:
- Linux-native and low-overhead. A pure-Rust daemon with no async
runtime in the hot path (sync +
pollingonly), sampling on demand and serving clients over a postcard-framed Unix socket. - Multi-GPU first. First-class sensors for NVIDIA (NVML), AMD (amdgpu), and Intel (xe + i915) GPUs — temperature, utilization, memory, power, and processes, per device.
- Extensible and scriptable. Everything the GUI shows is also a
linsight-clisubcommand, and new metric sources drop in as runtime.soplugins (ABI v6) without recompiling the daemon.
What it monitors today:
- GPUs: NVIDIA, AMD, and Intel (xe + i915), with per-device nicknames.
- System: CPU, memory, NVMe, disk, filesystem, network, hwmon, ZRAM, processes, systemd units, and PSI / load / uptime.
- Runtime plugins: drop a
.soin to add sensors; the bundled sensors are themselves in-tree plugins. Per-plugin TOML config. - Custom dashboards & themes: preset pages (Overview / GPUs / Storage / Network / Hardware) plus a drag-and-drop canvas editor.
- Alerts:
evalexprrules with anexec:<argv>notifier (no shell injection). - History & metrics: optional SQLite history and a Prometheus
exporter with a stable
device_keylabel. - Remote: an mTLS bridge (
linsight-tunnel) for non-SSH topologies.
GUI
cargo run -p linsight
# Kirigami window with a left sidebar:
# Workspace → Overview / GPUs / Storage / Network / Hardware / Editor
# System → Settings / About
# Auto-spawns linsightd as a child if no daemon is running.Keyboard shortcuts: Ctrl+1..5 for the workspace pages, F1 for
About, StandardKey.Preferences for Settings.
CLI
just run-daemon # or let the GUI spawn it
just run-cli list # sensor catalogue (52+ entries)
just run-cli read cpu.util --count 5
just run-cli read mem.used_bytes --count 3
just run-cli plugin new my-sensor # scaffold a third-party plugin
just run-cli db stats # row count, sensors, time span, file size
just run-cli db prune --older-than 7d # delete rows older than 7 days
just run-cli db prune --older-than 7d --vacuum # also reclaim file spaceRemote (mTLS, non-SSH topologies)
# On the remote machine running linsightd. Default bind is
# 127.0.0.1:9443; pass --bind 0.0.0.0:9443 to expose to the network.
linsight-tunnel server \
--bind 0.0.0.0:9443 \
--cert server.pem --key server.key --ca clients-ca.pem \
--socket /run/user/1000/linsight.sock
# On your desktop:
linsight-tunnel client \
--listen $XDG_RUNTIME_DIR/linsight-remote.sock \
--server remote.host.example:9443 \
--cert client.pem --key client.key --ca server-ca.pemAny LinSight client then connects to the local socket as usual; bytes
are piped over mTLS to the remote daemon. See
apps/linsight-tunnel/README.md for a
topology diagram, an openssl cert recipe, and the trust-model caveats.
For most remote use, an SSH-forwarded socket
(ssh -L $XDG_RUNTIME_DIR/linsight.sock:remote-runtime/linsight.sock host)
is simpler and equally secure.
Remote host switching in the GUI
The Settings page lets you save remote hosts (ssh://[user@]host[:port])
and switch between them from the sidebar dropdown. Hosts are persisted in
~/.config/linsight/hosts.json. Selecting a host reconnects the GUI to that
daemon; a failed reconnect keeps the previous connection alive and shows an
error banner. You can also launch straight to a remote host with
linsight --connect ssh://user@host. Key-based SSH authentication is
assumed; the trust model is the same as using ssh -L manually.
LinSight is a standard Cargo workspace (resolver 3, edition 2024, stable
Rust pinned via rust-toolchain.toml). Everything goes through just;
direct cargo invocations are equivalent if just isn't installed.
just ci # fmt-check + clippy -D warnings + tests (the CI gate)
just test-release # same tests in release mode (catches opt-level bugs)
just bench # Criterion benchmarks for protocol/core hot paths
just build # debug
just build-release # release: lto=fat, codegen-units=1, strip
just build-release-v3 # x86_64-v3 tuned (CachyOS / modern systems)GUI smoke (headless, requires xvfb-run):
just gui-smoke # builds release GUI and runs under xvfb + llvmpipeOptional preflight (install with
cargo install cargo-deny cargo-audit cargo-about):
just preflight # ci + deny + audit
just credits # cargo about generate → docs/third-party-notices.mdInstall LinSight as a pacman-tracked package rather than hand-copying
binaries into /usr/. For local development, build the working tree and
install it via pacman:
cd packaging/arch
makepkg -si -p PKGBUILD.local # build the working tree, install via pacman| Target | Command |
|---|---|
| Arch (local dev) | makepkg -si -p packaging/arch/PKGBUILD.local |
| Arch (release) | makepkg -si -p packaging/arch/PKGBUILD (from a tag) |
PKGBUILD.local lays down the binaries, desktop entry, metainfo, the
user systemd unit, hicolor icons, and /usr/lib/linsight/plugins.
Manage it like any package — pacman -Qi linsight to inspect,
sudo pacman -R linsight to remove.
packaging/systemd/linsight.service is a systemd user unit. Enable
it once to keep the daemon resident; the GUI / CLI then attach to the
existing socket. Always-on mode also gates the optional surfaces —
history (LINSIGHT_HISTORY), alerts (LINSIGHT_ALERTS), and the
Prometheus exporter (LINSIGHT_PROM_BIND), all off by default. The
Settings page shows each subsystem's env-var status.
When history is enabled, LINSIGHT_HISTORY_RETENTION controls how long
samples are kept. The format is an integer with a d, h, or m suffix
(e.g. 30d, 12h, 45m). Unset defaults to 30d; 0 keeps rows
forever. An unparseable value logs a warning and falls back to 30d.
The daemon prunes rows older than the window at most once per hour, with
the first prune ~5 minutes after startup. The database file does not
shrink after pruning — freed pages are reused; use
linsight-cli db prune --vacuum for offline space reclamation.
apps/linsightd/— daemon; hosts plugins, schedules subscription-driven sampling, serves clients over a postcard-framed Unix socket. Optional history (SQLite), alerts (evalexpr), Prometheus exporter.apps/linsight-gui/— Qt 6 / Kirigami GUI via cxx-qt 0.8. Sidebar shell, preset pages, canvas editor, multi-window. Auto-spawns the daemon if none is listening.apps/linsight-tunnel/— mTLS bridge for the daemon socket (server/clientsubcommands; transparent byte pipe). The only binary that uses tokio — never the daemon hot path.crates/linsight-core/— shared types and dashboard model (no I/O).crates/linsight-protocol/— postcard wire format + framing.crates/linsight-plugin-sdk/— publicLinsightPlugintrait +export_plugin!macro. ABI v6 uses R-mirror types on the FFI boundary for cross-rustc safety; seedocs/adr/0001-plugin-abi-stabby-deferral.md.crates/linsight-sensors/*— one in-tree plugin per hardware family / metric source (cpu, mem, net, nvme, nvml, xe, amdgpu, i915, disk, fs, hwmon, proc, system, systemd, zram, smart, sock).crates/linsight-cli/—list/read/plugin {new, install, ls, remove}/db {stats, prune}(offline history-DB inspection and maintenance; works without a running daemon).examples/echo-plugin/— minimal third-party plugin built as acdylib; exercised by the SDK'stests/dynamic_load.rs.
See docs/architecture.md for the full process
model and data flow.
Patches, bug reports, and design feedback are welcome. The full guide —
fork → branch → PR flow, coding standards, and commit style — lives in
CONTRIBUTING.md. Quick rules of thumb:
- Branch from
master, send a PR. - Run
just cilocally before pushing — it must pass (it's the same gate CI runs). - LinSight is GPL-3.0-only; new dependencies must use a license in
deny.toml's allowlist.
Bugs / feature requests: GitHub issues.
GPL-3.0-only. See LICENSE. Third-party license credits live
in docs/third-party-notices.md.


