Introduction to rouser
What is rouser?
rouser is a Linux daemon that monitors system metrics and automatically inhibits sleep when activity thresholds are exceeded. It enables systems to:
- Sleep automatically after idle time when no activity is detected
- Stay awake during high CPU/GPU usage (compiling, rendering, gaming)
- Remain active during network transfers or disk I/O
Purpose and Use Cases
Headless Servers
Keep your headless server awake during: - Large file downloads or uploads - Database operations with high disk I/O - Network backup jobs - Compilation or build processes
Desktop Systems
Prevent unwanted sleep during: - Video rendering or 3D work - Gaming sessions - Long-running downloads - Local network activity
Development Workstations
Maintain system responsiveness during: - Code compilation - Container builds - Docker operations - Virtual machine execution
How It Works
rouser operates on a simple principle:
- Monitor: Collects CPU, GPU, network, and disk metrics at regular intervals (default: 5 seconds)
- Evaluate: Compares metrics against configurable thresholds
- Decide: Determines if activity warrants keeping the system awake
- Inhibit: Uses systemd's login1 D-Bus API to prevent sleep when thresholds are exceeded
Key Design Decisions
Why systemd login1?
rouser uses the org.freedesktop.login1.Manager.Inhibit D-Bus API because:
- Actively maintained and well-documented
- Works reliably across desktop environments
- Doesn't require session D-Bus (works without a graphical session)
- Standard interface for sleep inhibition on modern Linux systems
Why Rust?
- Memory safety without garbage collection
- Zero-cost abstractions for efficient metric collection
- Native async runtime support via Tokio
- Strong type system prevents configuration errors
- No external C dependencies
Why TOML Configuration?
TOML was chosen over YAML because:
- Pure Rust implementation with no C dependencies
- Simpler, more readable syntax
- Better security (avoids RUSTSEC-2025-0068 vulnerability in YAML parsers)
- Native support via the
tomlcrate
CI/CD Coverage
rouser is built and packaged via GitHub Actions for multiple architectures on every release:
| Target | Build Status | Package Formats Available |
|---|---|---|
| x86_64 Linux | Built & tested | Tarball + DEB (amd64) + RPM (x86_64) |
| aarch64 Linux | Cross-compiled & tested | Tarball + DEB (arm64) + RPM (aarch64) |
| Arch / Bazzite | Built on release | PKGBUILD archive |
Pre-release: rouser is at
v0.0.0(unreleased). No official releases yet. See AGENTS.md for versioning policy.
System Requirements
Minimum Requirements
| Resource | Value |
|---|---|
| OS | Linux with systemd (v219+) |
| CPU Architecture | x86_64 or aarch64 (pre-built binaries available via CI pipeline) |
| Memory | 64 MB free |
| Disk | 10 MB free |
Recommended Requirements
| Resource | Value |
|---|---|
| OS | Latest stable systemd |
| CPU Architecture | x86_64 (native) or aarch64 (cross-compiled, same binaries work on both) |
| CPU | Dual-core or better |
| Memory | 128 MB free |
| Disk | 50 MB free |
GPU Requirements (Optional — for GPU Monitoring)
GPU monitoring is optional; rouser operates fully without any GPU. When GPUs are present, the following drivers and data sources are supported:
| Vendor | Driver / Data Source | Notes |
|---|---|---|
| NVIDIA | Proprietary driver with NVML library (libnvidia-ml.so) |
Per-GPU utilization via NVML API (same approach as nvtop) |
| AMD | Open-source amdgpu kernel module |
Sysfs path /sys/class/drm/cardN/device/gpu_busy_percent |
| Intel | i915 or xe kernel module |
Same sysfs path as AMD; driver detected via device/driver symlink target |
NVIDIA GPU monitoring uses the NVML library (libnvidia-ml.so) loaded dynamically at runtime — no separate binary required. The NVML library is included with NVIDIA proprietary drivers and is also used by tools like nvidia-smi and nvtop. AMD and Intel GPUs require no external binaries beyond standard kernel interfaces.
Performance Characteristics
Resource Usage (Typical)
| Metric | Value | Notes |
|---|---|---|
| Memory | ~2-5 MB | Depends on interfaces/devices |
| CPU | <0.1% | With 5-second polling interval |
| Disk I/O | Negligible | Reads from /proc filesystem |
| Power Impact | ~1-2 mW | Additional daemon overhead |
Latency
- Response Time: From threshold exceedance to sleep inhibition (~5-10 seconds)
- Configurable: Adjust polling interval and thresholds for faster response
Architecture Overview
┌──────────────┐ ┌───────────┐ ┌───────────┐
│ Config │───▶│ Core │◀───│ Metrics │
│ Loader │ │ Logic │ │ Collectors│
└──────────────┘ └─────┬─────┘ └───────────┘
│
┌────▼────┐
│Threshold│
│Manager │
└────┬────┘
│
┌────▼────┐
│Inhibitor│
└────┬────┘
│
org.freedesktop.login1
Component Descriptions
- Config Loader: Parses TOML configuration and applies defaults
- Core Logic: Main event loop coordinating all components
- Metrics Collectors: Modular collectors for CPU, GPU, network, disk
- Threshold Manager: Tracks metrics over time and determines inhibition state
- Inhibitor: Interfaces with D-Bus to acquire/release sleep inhibition locks
Security Considerations
Principle of Least Privilege
rouser is designed to run as a systemd user service under the unprivileged invoking user's account — no root access required for normal operation. The recommended installation path (via installer script or manual setup) places the binary and config in ~/.local/bin/ and ~/.config/rouser/config.toml, respectively.
When running as a user service, rouser only needs:
- Read access to /proc filesystem entries (/proc/stat, /proc/net/dev, /proc/diskstats) — available to any process on the system
- D-Bus session bus access via org.freedesktop.login1.Manager.Inhibit for sleep inhibition (may require a polkit rule on some desktop environments like KDE Plasma)
- Optional: read access to sysfs paths (/sys/class/drm/cardN/device/gpu_busy_percent) for AMD/Intel GPU monitoring — typically world-readable
A system-wide installation under root is possible but not recommended; see Running as a Service for details.
File Permissions (User-Mode, Recommended)
| Path | Permission | Notes |
|---|---|---|
Binary (~/.local/bin/rouser) |
0755 |
User-owned executable |
Config (~/.config/rouser/config.toml) |
0644 (or stricter) |
Owned by user; no sensitive data is stored in config |
Log directory (~/.local/log/rouser) |
0755 |
Writable by daemon user only |
File Permissions (System-Mode, Optional — Requires Root)
When installing system-wide under root:
| Path | Permission | Notes |
|---|---|---|
Binary (/usr/local/bin/rouser) |
0755 root-owned executable |
Installed via DEB/RPM or manual copy as root |
Config (/etc/rouser/config.toml) |
0644 root-owned, group-readable |
No secrets in config; readable by all users is acceptable |
Service file (/lib/systemd/system/rouser.service) |
0644 systemd-managed |
Standard systemd service permissions |
Desktop Environment Considerations
- KDE Plasma: Powerdevil may ignore D-Bus inhibitors from unprivileged users. A polkit rule at
/etc/polkit-1/rules.d/50-rouser.rulesis recommended (see systemd-user-service.md).
Release Artifacts
On every tagged release, GitHub Actions publishes build artifacts matching your architecture (x86_64 or aarch64):
| Artifact | Format | Description |
|---|---|---|
| Tarball archive | .tar.gz |
Contains binary + default config (config/rouser.toml) + systemd service file. Extract and install components manually, or use the installer script to handle it automatically. Available for x86_64 and aarch64. |
| DEB package | .deb |
Debian/Ubuntu native package built in GitHub Actions. Installs binary to /usr/local/bin/, config to /etc/rouser/config.toml, service file to /lib/systemd/system/. Available for amd64 and arm64. |
| RPM package | .rpm |
Red Hat/Fedora/CentOS native package built in a containerized fedora:latest image. Installs binary, config, and systemd service file at standard paths. Available for x86_64 and aarch64. |
| Arch PKGBUILD | .tar.gz (source archive) |
Archive containing PKGBUILD with source URLs pointing to all release tarballs. Download from the releases page and build locally via makepkg. Suitable for Arch Linux, Bazzite, and other Arch-based distros. |
Installer Script
The provided installer script (scripts/install.sh) automates manual installation: it downloads the latest release tarball matching your architecture, extracts the binary to ~/.local/bin/, installs default config to ~/.config/rouser/config.toml, and enables the systemd user service. Run curl -fsSL <url>/install.sh | bash -- --help to see available options before installing.
Installation Methods Summary
| Method | Best For | Root Required? |
|---|---|---|
Cargo build (cargo build) |
Developers, custom targets | No (for user install) |
Installer script (install.sh) |
Quick setup on any distro | No (user-mode only) |
| DEB package (.deb) | Debian/Ubuntu servers and desktops | Yes (system-wide install via dpkg -i) |
| RPM package (.rpm) | Fedora/RHEL/CentOS/AlmaLinux | Yes (system-wide install via dnf or rpm -i) |
| Arch PKGBUILD | Arch Linux, Bazzite, and derivatives | No (user-mode build) |
License
This project is licensed under the MIT License. See the LICENSE file for details.
Getting Started
- Installation — Get rouser running on your system within 5 minutes
- Configuration Reference — Complete configuration options with defaults and examples
- Command Line Arguments — CLI usage, flags, and environment variables
- Running as a Service — Systemd user service setup, hardening, and troubleshooting
- Metrics Overview — How each metric type is collected (CPU, GPU, network, disk)
- Developer Guide — Build process, code structure, and contribution guidelines
See Also
- CI Workflow — GitHub Actions pipeline: lint gates, cross-compilation, DEB/RPM/PKGBUILD packaging, release artifacts
- AGENTS.md — Developer conventions: versioning policy, commit format, error handling, async patterns