Summary
all-smi already collects and exports system swap statistics on every platform, but the TUI view mode never displays them. This issue tracks surfacing swap usage (total / used / free) in the interactive view so users can spot swap pressure at a glance — most importantly on Apple Silicon, where an over-sized model or mismatched inference-engine parameters spill unified memory into swap and silently degrade throughput.
The data plumbing is already in place; this is primarily a rendering enhancement.
Background
The requester monitors AI inference workloads on Apple Silicon. When a model or its runtime parameters don't fit the available unified memory, macOS begins swapping, which tanks inference performance without an obvious signal. They want a single pane of glass in all-smi view that shows when the system is swapping.
Current state of swap support across the codebase:
| Layer |
Status |
Reference |
Data model (MemoryInfo has swap_{total,used,free}_bytes) |
✅ |
src/device/types.rs:365-378 |
macOS collection (sysinfo total/used/free_swap()) |
✅ |
src/device/memory_macos.rs:67-69 |
Linux collection (/proc/meminfo SwapTotal/SwapFree) |
✅ |
src/device/memory_linux.rs:105-106,137-139 |
| Windows collection (page file via sysinfo) |
✅ |
src/device/memory_windows.rs:70-72 |
Prometheus/API export (all_smi_swap_{total,used,free}_bytes) |
✅ |
src/api/metrics/memory.rs:75-113,167 |
| Public lib API + docs |
✅ |
docs/LIB_mode.md:494-518 |
| TUI detailed memory section |
❌ not displayed |
src/ui/renderers/memory_renderer.rs:58-165 |
| TUI compact local header |
❌ RAM only, no swap |
src/ui/local_header.rs:197-219 |
Note: README.md:438-439,878 already advertises "Swap space monitoring" / "System and swap memory statistics," so this is also a docs-vs-UI consistency fix — the feature is claimed but invisible in the primary interface.
Proposed Solution
Render swap in the detailed memory section (print_memory_info), which appears in both local mode (src/view/frame_renderer.rs:756) and cluster/remote mode (src/view/frame_renderer.rs:603).
Recommended approach — a dedicated swap bar under the existing memory bar:
- Add a
BarSegment::swap_used(value) helper with a distinct color (e.g. magenta/orange) in src/ui/widgets.rs, alongside memory_used/memory_buffers/memory_cache (lines 283-293).
- In
print_memory_info (src/ui/renderers/memory_renderer.rs), after the existing Mem bar, draw a second Swap bar via draw_bar_multi using swap_total_bytes as the total and a swap_used segment, with a X.XGB label. Add Swap: <used>/<total>GB to the info line or bar label.
- Only render the swap row when
swap_total_bytes > 0 (mirrors the API exporter guard at src/api/metrics/memory.rs:76) so hosts without swap stay uncluttered. Always render it when swap_used_bytes > 0.
- Emphasize active swapping: color the swap value/bar amber or red when
swap_used_bytes > 0 (or above a small threshold). This is the core signal the requester needs.
Optional secondary: append a compact Swp <used>GB indicator (red when > 0) to the local header (draw_ram_sparkline, src/ui/local_header.rs:197) so the top summary line also flags swapping.
Alternatives considered:
- Inline text only (add
Swap: to the existing Total/Used/Avail/Util line, no bar): least code, but that line is already near the width budget and a bar is more legible.
- Swap as a segment inside the RAM bar: rejected — swap is backing store, not physical RAM; merging them misrepresents capacity.
Implementation Notes
- macOS dynamic swap: macOS manages swap dynamically (
dynamic_pager); swap_total_bytes may legitimately be 0 until the OS creates a swap file, then grow. The "show only when swap_total > 0" rule makes the swap row appear exactly when swap exists — desirable. Verify sysinfo's total_swap() reflects sysctl vm.swapusage on target macOS versions.
- macOS compression caveat: macOS compresses memory before swapping; "swap used" is post-compression bytes written to disk, distinct from compressed-but-resident memory. Keep the label simply "Swap" to avoid implying it fully captures memory pressure.
- Layout / height budget: adding a swap row adds one line to the memory section. In cluster mode, many nodes stack vertically — confirm per-node height accounting and the function-key reservation still hold (see CLAUDE.md "Content Overflow";
src/view/frame_renderer.rs). Conditional rendering keeps non-swap hosts unaffected.
- Mock server: Apple Silicon and NVIDIA mock templates hardcode swap to
0 (src/mock/templates/apple_silicon.rs:416-418,479-481; src/mock/templates/nvidia.rs:622-624,685-687), so the feature can't currently be demoed via mock. Set realistic non-zero swap (the generic generator already models swap growth in src/mock/metrics/memory.rs) for at least one template so reviewers can exercise the new UI.
- Tests:
memory_renderer.rs unit tests already build MemoryInfo with non-zero swap (lines 183-185); extend them to assert the swap row renders when present and is omitted when swap_total_bytes == 0.
- Docs/help: update the memory legend in the help overlay (
src/ui/help.rs:272,293) and the README memory section to describe the swap row and its colors.
Affected files (primary): src/ui/renderers/memory_renderer.rs, src/ui/widgets.rs, src/ui/local_header.rs (optional), src/mock/templates/apple_silicon.rs (+ nvidia.rs), src/ui/help.rs, README.md.
Acceptance Criteria
Original Suggestion
Title: Would be nice to show swap usage (going beyond simple "Disk /" usage)
Especially when working with AI workloads, s.a. on Apple-Silicon, a poor fit, poorly matched inference engine parameters, can lead to swap usage, degrading performance. It'd be good to have a single pane of glass view, in all-smi to see the swap usage on such a system.
Summary
all-smialready collects and exports system swap statistics on every platform, but the TUI view mode never displays them. This issue tracks surfacing swap usage (total / used / free) in the interactive view so users can spot swap pressure at a glance — most importantly on Apple Silicon, where an over-sized model or mismatched inference-engine parameters spill unified memory into swap and silently degrade throughput.The data plumbing is already in place; this is primarily a rendering enhancement.
Background
The requester monitors AI inference workloads on Apple Silicon. When a model or its runtime parameters don't fit the available unified memory, macOS begins swapping, which tanks inference performance without an obvious signal. They want a single pane of glass in
all-smi viewthat shows when the system is swapping.Current state of swap support across the codebase:
MemoryInfohasswap_{total,used,free}_bytes)src/device/types.rs:365-378total/used/free_swap())src/device/memory_macos.rs:67-69/proc/meminfoSwapTotal/SwapFree)src/device/memory_linux.rs:105-106,137-139src/device/memory_windows.rs:70-72all_smi_swap_{total,used,free}_bytes)src/api/metrics/memory.rs:75-113,167docs/LIB_mode.md:494-518src/ui/renderers/memory_renderer.rs:58-165src/ui/local_header.rs:197-219Note:
README.md:438-439,878already advertises "Swap space monitoring" / "System and swap memory statistics," so this is also a docs-vs-UI consistency fix — the feature is claimed but invisible in the primary interface.Proposed Solution
Render swap in the detailed memory section (
print_memory_info), which appears in both local mode (src/view/frame_renderer.rs:756) and cluster/remote mode (src/view/frame_renderer.rs:603).Recommended approach — a dedicated swap bar under the existing memory bar:
BarSegment::swap_used(value)helper with a distinct color (e.g. magenta/orange) insrc/ui/widgets.rs, alongsidememory_used/memory_buffers/memory_cache(lines 283-293).print_memory_info(src/ui/renderers/memory_renderer.rs), after the existingMembar, draw a secondSwapbar viadraw_bar_multiusingswap_total_bytesas the total and aswap_usedsegment, with aX.XGBlabel. AddSwap: <used>/<total>GBto the info line or bar label.swap_total_bytes > 0(mirrors the API exporter guard atsrc/api/metrics/memory.rs:76) so hosts without swap stay uncluttered. Always render it whenswap_used_bytes > 0.swap_used_bytes > 0(or above a small threshold). This is the core signal the requester needs.Optional secondary: append a compact
Swp <used>GBindicator (red when > 0) to the local header (draw_ram_sparkline,src/ui/local_header.rs:197) so the top summary line also flags swapping.Alternatives considered:
Swap:to the existing Total/Used/Avail/Util line, no bar): least code, but that line is already near the width budget and a bar is more legible.Implementation Notes
dynamic_pager);swap_total_bytesmay legitimately be0until the OS creates a swap file, then grow. The "show only whenswap_total > 0" rule makes the swap row appear exactly when swap exists — desirable. Verify sysinfo'stotal_swap()reflectssysctl vm.swapusageon target macOS versions.src/view/frame_renderer.rs). Conditional rendering keeps non-swap hosts unaffected.0(src/mock/templates/apple_silicon.rs:416-418,479-481;src/mock/templates/nvidia.rs:622-624,685-687), so the feature can't currently be demoed via mock. Set realistic non-zero swap (the generic generator already models swap growth insrc/mock/metrics/memory.rs) for at least one template so reviewers can exercise the new UI.memory_renderer.rsunit tests already buildMemoryInfowith non-zero swap (lines 183-185); extend them to assert the swap row renders when present and is omitted whenswap_total_bytes == 0.src/ui/help.rs:272,293) and the README memory section to describe the swap row and its colors.Affected files (primary):
src/ui/renderers/memory_renderer.rs,src/ui/widgets.rs,src/ui/local_header.rs(optional),src/mock/templates/apple_silicon.rs(+nvidia.rs),src/ui/help.rs,README.md.Acceptance Criteria
swap_total_bytes > 0.swap_total_bytes == 0) to avoid clutter.swap_used_bytes > 0./proc/meminfo.all-smi-mock-server+all-smi view).Original Suggestion
Title: Would be nice to show swap usage (going beyond simple "Disk /" usage)
Especially when working with AI workloads, s.a. on Apple-Silicon, a poor fit, poorly matched inference engine parameters, can lead to swap usage, degrading performance. It'd be good to have a single pane of glass view, in all-smi to see the swap usage on such a system.