No description
- C 99.1%
- Makefile 0.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Lists running programs by CPU, memory, or disk I/O: program name on the left, a proportional bar on the right. Everything comes from /proc, with ncurses the only dependency. - groups processes by program, so Firefox's content processes read as one firefox (x15) row rather than fifteen Isolated Web Co rows - disk rates come from read_bytes/write_bytes, which skip the page cache; rows we cannot read show - rather than 0 - x signals the selected row, re-reading each PID first so a stale row cannot signal whatever inherited its PID; PID 1 is never signalled - space freezes the display, and the cursor follows its program rather than a row number, so the sort order shifting does not move your aim Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016ZPgG8HFHXzdRmbc39knZF |
||
| .gitignore | ||
| hogs.c | ||
| Makefile | ||
| README.md | ||
hogs
A small terminal monitor for what is using this machine: program name on the left, a proportional usage bar on the right.
hogs 39 programs 8 cores every 1.5s sort:cpu abs
CPU 23.1% ████████▏ MEM 4.5G/15G ██████████
PROGRAM CPU USAGE (100% = one core)
yes 99.7% ██████████████████████████████████████▊
firefox (x15) 20.3% ███████▋
qemu-system-x86_64 3.9% █▌
claude (x2) 3.3% █▏
Sorting by disk instead (d) shows who is actually touching storage:
PROGRAM DISK DISK (read + write per second)
dd 1.2G/s █████████████████████████████████████████
journald 412K/s ▏
postgres (x9) -
Build
make # needs ncursesw
./hogs
make install # optional, PREFIX=/usr/local
Keys
| key | what it does |
|---|---|
q |
quit |
c / m / d |
sort by CPU / by memory / by disk I/O |
g |
group processes by program, or list them individually with PIDs |
r |
bar scale: absolute (one core / all RAM) or relative to the busiest row |
K |
show/hide kernel threads (shown in [brackets]) |
/ |
filter by name — Enter accepts, Esc clears |
| space | freeze the display; sampling stops until you press it again |
x, F9 |
signal the selected row — then t for SIGTERM, k for SIGKILL |
+ / - |
slower / faster refresh |
arrows, j/k, PgUp/PgDn, Home/End |
move the cursor; the list scrolls to follow |
Notes
- Everything comes from
/proc; no privileges needed and no dependencies beyond ncurses. - CPU% is per core, so a program using two cores fully reads 200%. In absolute
scaling the bar is full at 100% and marks the overflow with
>. - Disk I/O is
read_bytes+write_bytesfrom/proc/<pid>/io, which count bytes that actually reach storage rather than the page cache. That file is readable only for your own processes unless you are root, so other users' rows show-, meaning unknown rather than idle. - Disk rates have no natural full scale the way a core or total RAM does, so the bars are drawn against the recent peak, which decays between samples.
- Freezing (space) leaves the numbers exactly as they were. The first sample after unfreezing averages CPU over the whole frozen span, so it can read low for one tick.
xsignals the whole program when rows are grouped, so a row readingfirefox (x15)sends the signal fifteen times; pressgfirst to aim at a single PID. The prompt always names what it is about to signal.- The process list can be up to one refresh interval old, so before signalling
a PID hogs re-reads it and checks it is still the same program. A row for a
process that has since exited reports
already gonerather than signalling whatever inherited its PID. PID 1 is never signalled. - The cursor follows the program it is on rather than a row number, so it stays put when the sort order shifts underneath it.
- Memory is resident set size (RSS). Grouped rows add up the RSS of each process, which double counts memory that copies of a program share.
- Names come from
argv[0], falling back to the kernel'scommfor kernel threads. That is why Firefox's content processes group underfirefoxrather than appearing asIsolated Web Co.