System Yield over Desktop Bloat: Why I Migrated to Omarchy Linux & Terminal-Native Orchestration
Operating system performance is measured by System Yield: realized target output divided by the cognitive and material energy spent producing it. Desktop environments optimize for first-run impressions and inflate the denominator on every subsequent task. Moving to an opinionated Arch-based setup with Hyprland tiling and a keyboard-driven terminal reduces the denominator and turns the OS from a passive interface into an execution engine.
| Metric | Desktop GUI (Windows/macOS/heavy GNOME/KDE) | Omarchy + Hyprland + terminal-native |
|---|---|---|
| Context switches per task | Window, app, and modal hops, each with a pointer move | Workspace and pane focus, no pointer |
| Configuration surface | Settings wizards, registry or plist state, vendor toggles | Plain-text files under ~/.config,
version-controllable |
| Idle resource floor | Background agents, telemetry, indexers, update daemons | Units you wrote or explicitly enabled |
| Failure diagnosis | Event Viewer, Console.app, vendor dialogs | journalctl, systemctl, ss,
/proc |
| Automation boundary | Per-app macros, vendor APIs | Any process reachable from a shell pipeline |
The Cognitive Tax of GUI-Centric Computing
GUI workflows impose a tax that does not appear on any benchmark: the cost of translating intent into pointer coordinates.
- Modal friction: every dialog, wizard, and nested settings pane forces a context switch away from the task.
- Non-introspectable state: GUI settings live in
opaque stores. You cannot
grepthem, diff them, or reproduce them on a second machine. - Vendor-owned defaults: notifications, sync prompts, and onboarding flows are product decisions you pay for in attention each time they fire.
- Keyboard ceiling: most GUI apps expose a fraction of their functionality through shortcuts. The rest requires pointer navigation.
A POSIX environment inverts each of these. Intent maps directly to a command, state is text, and the same config reproduces on any node. The cost per action drops to a keystroke and a read.
Architecture & Stack
The stack is deliberately small. Each layer has one owner and one responsibility.
| Layer | Component | Role |
|---|---|---|
| Base | Arch Linux via Omarchy | Rolling base, opinionated defaults, no vendor services by default |
| Display | Wayland + Hyprland | Keyboard-driven tiling compositor, workspaces as first-class objects |
| Shell | Fish or Bash | Scripted, scriptable interactive shell with reproducible config |
| Services | systemd | Unit discipline: every long-running process is a unit with logs and restart policy |
| Network | SSH over a Tailscale overlay | Encrypted node-to-node reach without public ingress |
Hyprland Bindings as Control Surface
Window management is config, not interaction. A representative fragment:
# ~/.config/hypr/bindings.conf (excerpt)
bind = SUPER, Return, exec, $terminal
bind = SUPER, 1, workspace, 1
bind = SUPER SHIFT, 1, movetoworkspace, 1
bind = SUPER, H, movefocus, l
bind = SUPER, L, movefocus, r
Focus, placement, and workspace moves are single chords. No pointer path exists in the critical loop.
systemd Unit Discipline
Background work is a unit, not a forgotten process. A user-scope service with explicit restart policy:
# ~/.config/systemd/user/nightly-sync.service
[Unit]
Description=Nightly repository sync
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/bin/env bb /home/%u/bin/sync.bb
Inspection uses the same primitives every time:
systemctl --user list-units --type=service --state=running
systemctl --user status nightly-sync.service
journalctl --user -u nightly-sync.service -b --no-pager
Remote Nodes Over Overlay Networking
Remote machines are addressed by name over an encrypted overlay, reached with the same tools as local ones:
ssh build-node.example 'journalctl -p err -b --no-pager | tail -n 50'
Access control is an SSH key and a tailnet ACL, not a public port. Nothing listens on the internet.
The Terminal as an LLM Orchestration Harness
The terminal is the common interface for every tool in the workflow. An LLM agent is one more process that reads stdin, writes stdout, and respects exit codes. This is the property that makes the terminal a control plane rather than a window.
- Kilo runs inside a terminal pane and operates on the working tree directly.
- Babashka (
bb) scripts handle repository data without a build system or a runtime install. - POSIX pipelines (
grep,awk,sed,sort,uniq) provide deterministic filtering around nondeterministic model output.
A representative pipeline: find recent error signatures across services, count them, and hand the top offenders to a model for triage.
journalctl -p err -b --no-pager -o short-iso \
| awk '{ $1=""; $2=""; print }' \
| sed -E 's/[0-9a-f]{8,}/<hex>/g; s/[0-9]+/N/g' \
| sort | uniq -c | sort -rn | head -n 20
Structured data uses Babashka with the bundled cheshire
JSON library:
cat deploy-report.json | bb -e \
'(require (quote [cheshire.core :as json]))
(let [m (json/parse-string (slurp *in*) true)]
(doseq [f (:failures m)] (println (:unit f) (:reason f))))'
The design rule: the model proposes, deterministic tools verify. Grep and Babashka produce the evidence; the model interprets it. Every model action is reproducible from a shell history and a log.
Bare-Metal Mastery vs. Abstraction
Abstraction layers are useful only while they work. When they fail, the operator needs primitives.
- File permissions:
ls -l,stat,chmod, andgetfaclanswer access questions that GUI permission dialogs obscure. - Process management:
ps,lsof,ss -tlnp, and/proc/<pid>/expose the actual state of the machine. - Log analysis:
journalctl -u,-p,-b, and--sinceproduce scoped, timestamped evidence in seconds.
Knowing these primitives changes the failure mode. A GUI admin tool shows a status icon and a “Fix” button. A primitive shows the cause, and the fix is a one-line change you can commit.
The cost is real. Primitives have a steeper learning curve, and an
incorrect chmod -R or a wrong systemctl target
can break a session. The mitigation is discipline: read before writing,
keep configs in version control, and prefer reversible operations.
Conclusion
The operating system is a malleable component of the operator’s workflow, not a fixed consumer product. A keyboard-first tiling compositor, systemd-managed services, and a terminal that hosts both deterministic tools and language models reduce the energy required per unit of output.
System Yield is not a measured quantity in this setup, and no benchmark claims it. It is a decision rule: when a change adds a modal dialog, a hidden state store, or an unobservable background process, it lowers yield and gets rejected.