← Blog May 23, 2026

# Auto-standby: SIGSTOP for idle agent terminals

When you run a dozen agents across a dozen repos, most of them are idle most of the time — and a few of them are quietly spinning anyway. Auto-standby freezes the entire process group of a tab that's been unfocused and idle long enough, and unfreezes it the instant you look back.

## The quiet CPU tax

The whole point of TUICommander is running many agents at once. But "many agents" means many process trees, and not all of them sit politely at zero when they have nothing to do. A watch loop here, a dev server there, a TUI that repaints on a timer — individually trivial, collectively a steady drain on CPU and, on a laptop, battery. You're paying for terminals you aren't even looking at.

You could close them, but then you lose the session. You could remember to suspend them by hand, but you won't. The OS already has the right primitive for "pause this and let it resume exactly where it was" — job-control signals. We just needed to apply them automatically and safely.

## The rule: unfocused and idle and patient

A background checker ticks every 30 seconds and walks every session. A tab enters standby only when all of these hold:

- The standby timeout is enabled (`standby_timeout_minutes > 0`).
- The tab is not focused — you're not looking at it.
- Its shell state is idle — no command is running.
- It's been idle for at least the configured timeout.
- It isn't already in standby.
- Its startup has settled — we never freeze a session mid-boot.

The "unfocused AND idle" pairing is the important part. Idle-but-focused means you're reading the output, so we leave it alone. Unfocused-but-busy means it's doing real work in the background — also left alone. Only a tab that's both out of sight and doing nothing is a candidate, and even then only after it's been that way for a while. The default timeout is 5 minutes; `0` disables the feature entirely. It lives under Settings > General > Auto-Standby Timeout.

## Freeze the whole tree, not just the shell

When a session qualifies, we send `SIGSTOP` to the negative PID of the process-group leader — `kill(-pgid, SIGSTOP)` — which stops the entire process group, not just the top-level shell. That matters: the thing burning CPU is usually a child (the dev server, the agent's node process), not the shell itself. Stopping only the leader would leave the actual culprit running.

Power tools cut both ways, so there's a guard: before signalling, we validate the pgid and refuse to act on an unsafe one. Sending a stop signal to the wrong group — or to group 0, which means "every process in my group" — would be catastrophic, so that path simply errors out instead of firing.

## Waking up is instant and automatic

A frozen tab is useless if you have to manually thaw it. Standby is reversed with `SIGCONT` the moment either of two things happens: you focus the tab, or a message arrives for that agent. The process resumes exactly where it stopped — same memory, same open files, same scroll position — because `SIGSTOP`/`SIGCONT` is suspend-and-resume, not kill-and-restart. There's no session loss and no "reconnecting" state to wait through. A small pause badge in the tab bar tells you which tabs are currently sleeping.

## The tradeoffs

This is a Unix feature — it's built on POSIX job-control signals and is compiled in only on Unix targets. A process that holds a network connection or a lock while stopped will keep holding it; for the local dev tools and agents this targets that's fine, but it's the reason we gate on idle-and-unfocused rather than freezing aggressively. And we deliberately chose signals over killing-and-restarting: restarting would reclaim more memory, but it would also destroy session state, which defeats the purpose. Pausing is the honest answer to "I'm not using this right now, but I will be."

## What's next

The obvious extension is smarter wake triggers — resuming a standby session just before a scheduled job or an inbound agent hand-off, rather than only on focus. The checker already has the session model it needs; it's a question of which events deserve to count as "you're about to need this again".