Open-source project
matthart1983/diskwatch avatar
matthart1983/diskwatch

DiskWatch: a read-only disk diagnostics TUI for one machine at a time

Single-host, read-only disk diagnostics TUI. Sibling to netwatch and syswatch.

449 stars26 forksRustMIT

At a glance

What is it?
DiskWatch is a Rust terminal UI that consolidates lsblk, df, iostat, smartctl and hot-file tracing into eight tabs on a single host. It is read-only by design, which is both its clearest strength and its hardest boundary.
Who is it for?
Adopt DiskWatch if you diagnose one Linux or macOS machine at a time and want device, volume, filesystem, IO, SMART and hot-file data on one screen without stitching six commands together. Do not adopt it if you need fleet-wide history, remote collection, or a write path to disks; it is single-host and read-only by design.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 18, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem DiskWatch addresses for single-host debugging

When a disk light will not stop blinking, the usual response is a sequence of unrelated commands. `iostat -x 1` for throughput, `df -h` for capacity, `smartctl -A` for wear, `lsof` for whoever is holding a file open. Each answers one question and prints in its own format. DiskWatch's README frames itself as "the terminal you open when the disk light won't stop blinking", which is a fair description of the intended moment: a single machine, a suspected storage problem, and no time to assemble a picture by hand.

The target user is an engineer with shell access to the affected host. Not a fleet operator, not someone building a dashboard. The README lists what each tab replaces: `lsblk`, `nvme list`, `diskutil list`, `hdparm -I`, `lvs`, `vgs`, `mdadm --detail`, `df -h`, `df -i`, `mount`, `findmnt`, `iostat -x 1`, `smartctl -A`, `nvme smart-log`, `fatrace`, `fs_usage`, `lsof`. That list is the product statement. DiskWatch is a consolidation layer over tools that already exist on the box, not a new data source.

Read-only is a deliberate constraint, and it shapes everything else. DiskWatch will not partition, format, mount, or repair. It observes. That makes it safe to run on a machine you are worried about, and it also means the tool stops at diagnosis.

How DiskWatch gathers and presents data

The architecture is a Rust binary built on ratatui and crossterm for the terminal layer, with sysinfo for host metrics, notify for the file event stream, and libc for direct system calls. The Cargo.toml comments state that notify uses the raw event stream rather than the debounced API, with FSEvents on macOS and inotify on Linux. That choice matters for the Hot Files tab: debouncing would smooth over the bursts the tab is meant to surface.

Data flows from platform sources into per-tab views. On Linux the README says there are no system dependencies; on macOS it relies on the preinstalled `ioreg`, `diskutil` and `system_profiler`. Full SMART attribute tables require `smartmontools`; without it the SMART tab falls back to the basic verified/failing flag. That fallback is stated plainly, which is better than a tab that silently shows less than the user expects.

The most interesting mechanism is the Hot Files PROCESS column, and the README is unusually honest about it. Neither inotify nor FSEvents carries a pid, so the column is a join, not a measurement. DiskWatch reads per-process byte rates from `/proc/<pid>/io` and `proc_pidinfo`, and open file descriptors from `/proc/<pid>/fd` and `PROC_PIDLISTFDS`, then names the busiest process holding each hot path open. The README states the alternative directly: exact pid per event needs fanotify with `FAN_REPORT_PID` or eBPF, both of which require root. DiskWatch runs as the invoking user and infers instead.

Two limits are documented on the tab itself. Sampling happens every 2s, so a writer that opens, writes and closes between samples is missed; the README names compilers, `git` and package managers as the usual casualties. Unprivileged, it sees only your uid, and the banner counts processes it could not read so an empty column explains itself rather than looking broken. `sudo diskwatch` attributes the rest.

There are three layouts. Full has eight tabs: Overview, Devices, Volumes, FS, IO, SMART, Hot Files, Insights. Dense (`diskwatch --dense`) puts six boxes on one screen with no chrome rows, moving keybinds, sort state and page counters into box borders, and falls back to a compact screen below 104x32 while keeping the mirror and percentiles. Lite (`diskwatch --lite`) is 80x24 with six keys and no tabs, sized for a tmux split or an SSH session to a NAS.

Installing DiskWatch and reading the IO tab

The README lists five package routes. Homebrew covers macOS and Linux, Nix covers NixOS, `paru` covers Arch, and `cargo install` works anywhere with a Rust toolchain.

bash
brew install diskwatch                # macOS / Linux
nix-shell -p diskwatch                # NixOS / Nix
paru -S diskwatch                     # Arch
cargo install diskwatch               # anywhere with Rust
x eget use matthart1983/diskwatch     # prebuilt release binary

Prebuilt binaries are also published on the Releases page for Linux and macOS on x86_64 and aarch64, including static musl builds and an armv5te build aimed at older Marvell Kirkwood NAS boxes such as the Iomega ix2-dl running Debian. Windows x86_64 binaries exist too; the README says to extract the archive and run `diskwatch-windows-x86_64.exe`.

Building from source requires Rust 1.75 or newer, which matches the `rust-version` field in Cargo.toml.

bash
git clone https://github.com/matthart1983/diskwatch.git && cd diskwatch
cargo build --release
./target/release/diskwatch

For a first real use, start with the IO tab on a host where something is writing. Run the binary with no arguments and press `5`, or jump straight there with the `--tab` flag. The README documents `--tab` as starting on a named tab, so the invocation follows that form.

bash
diskwatch --tab io

The IO tab shows per-device throughput, a 48s sparkline, and p50/p99 read and write figures, which the README positions as a replacement for `iostat -x 1`. If you are on a small terminal or over SSH, the Lite view is the better entry point:

bash
diskwatch --lite

At 80x24 Lite shows read and write throughput, a capacity line answering "how long have I got", and the busiest files. Pressing Enter opens a detail block naming the process holding the selected file; above 99 columns that becomes a PROCESS column. If you want the full SMART attribute tables rather than the basic verified/failing flag, install `smartmontools` first, then press `r` to force a SMART refresh.

Where DiskWatch stops being the right tool

The 2s sampling interval is the sharpest limitation, and it is not a bug to be fixed later. Compilers, `git` and package managers open, write and close faster than the sample period, so the Hot Files tab can miss exactly the workload a user is trying to identify. The README says this on the tab rather than burying it, which is the right call, but it still means the tab answers "what is holding files open over time" and not "what wrote this file".

Unprivileged runs see only the invoking user's processes. Running as root closes that gap, and the README recommends `sudo diskwatch` for attribution, but root changes the safety profile of a tool whose main selling point is read-only observation. The banner's count of unreadable processes is the honest middle ground: an empty column says why instead of looking broken.

SMART depth depends on an external package. Without `smartmontools`, the SMART tab shows only the basic verified/failing flag, so a user comparing DiskWatch against `smartctl -A` output will find less than they expected until they install it. That is a packaging dependency, not a design flaw, but it is a step the README does not put in the install block.

Finally, DiskWatch is single-host by construction. The Cargo.toml description says "single-host, read-only disk diagnostics TUI", and nothing in the README suggests remote collection, aggregation, or history beyond the 48s sparkline and the days-to-full projection. If your question is "which of my forty servers is filling up", DiskWatch is the wrong shape of tool.

DiskWatch compared with running the underlying tools directly

The obvious alternative is not another TUI. It is the set of commands DiskWatch replaces, run by hand or in a small script. `iostat -x 1` gives per-device extended statistics with a configurable interval; `smartctl -A` gives the full attribute table; `df -h` and `df -i` give capacity and inode usage; `fatrace` or `fs_usage` show file events.

The difference in approach is aggregation versus precision. The underlying tools are each authoritative within their own domain, and they can be sampled at whatever interval you choose, piped into a script, or logged over weeks. DiskWatch trades that flexibility for a single synchronized view where the IO mirror, the latency histogram, the capacity projection and the hot-file list share a time axis and a colour scheme. Its latency tab uses seven buckets from `<0.1ms` to `>50ms` with p50/p95/p99 and the share of ops past 10 ms, colouring bars by bucket rather than by count so the tail is visible before it fills. Reproducing that by hand means writing a histogram.

The sibling projects matter here too. DiskWatch is described as a sibling to NetWatch and SysWatch, with the same chrome, palette and keys. For someone already running NetWatch, the keybindings transfer, which is a real cost saving. For someone who is not, that consistency is worth nothing.

The honest comparison: if you need a number you can log, alert on, or replay later, use the underlying tools. If you need to see the shape of a live problem on one machine and decide what to do next, DiskWatch compresses that step.

Maintenance, upgrades and the MIT licence

The repository is not archived, and the last push was on 2026-09-15. Three releases landed in the two days before that: v0.5.6 and v0.5.7 on 2026-09-14, and v0.5.8 on 2026-09-15, labelled "Live Windows I/O metrics". That cadence is fast, which cuts both ways. Fixes arrive quickly; interfaces can move quickly too.

Upgrade cost depends on how you installed it. Homebrew, Nix, Arch and `cargo install` all have their own update paths, and the README notes that the Nix and Arch packages are maintained by community packagers, with a clear split: packaging issues go to the packagers, diskwatch bugs go to the project. That split is worth remembering before filing an issue. Repology is linked as the place to check which packaged versions are current.

Dependency surface is small and pinned in Cargo.toml: ratatui 0.29, crossterm 0.28, sysinfo 0.32, clap 4, notify 7, plus anyhow, chrono, serde, serde_json, libc and unicode-width. The release profile uses thin LTO, one codegen unit and stripped binaries, which keeps the artifact small. The `unicode-width` dependency is there for a specific reason documented in the file: column clamping in the Lite view must be display-width aware because a CJK filename would otherwise shear every column to its right. That is a detail most terminal tools get wrong.

The licence is MIT, stated in both the README badge and Cargo.toml. MIT is permissive: it allows use, modification and redistribution provided the copyright notice and permission notice are retained. That is a factual description of the licence terms, not legal advice, and anyone embedding DiskWatch in a distributed product should read the LICENSE file rather than rely on this summary.

Editorial conclusion

Adopt DiskWatch if you diagnose one Linux or macOS machine at a time and want device, volume, filesystem, IO, SMART and hot-file data on one screen without stitching six commands together. Do not adopt it if you need fleet-wide history, remote collection, or a write path to disks; it is single-host and read-only by design. Before relying on the Hot Files tab, run `sudo diskwatch` once and compare the unread-process count in the banner against a plain run, because the PROCESS column is a 2s join over per-process byte rates and open file descriptors, not a measured pid per event.

Frequently asked questions

What is DiskWatch and what is its purpose?

DiskWatch is a single-host, read-only disk diagnostics TUI written in Rust, described in its Cargo.toml as eight tabs across devices, volumes, filesystems, IO, SMART, hot files and insights. It consolidates commands such as lsblk, df, iostat and smartctl into one terminal view. It is the sibling to netwatch and syswatch, sharing the same chrome, palette and keys.

How do I install DiskWatch?

The README lists five routes: brew install diskwatch on macOS and Linux, nix-shell -p diskwatch on NixOS, paru -S diskwatch on Arch, cargo install diskwatch anywhere with Rust, and x eget use matthart1983/diskwatch for a prebuilt release binary. Prebuilt binaries are also published on the Releases page for Linux and macOS on x86_64 and aarch64, plus static musl and an armv5te build for older NAS boxes.

Does DiskWatch need root to show which process is writing a file?

Unprivileged, DiskWatch sees only your uid, and the banner counts the processes it could not read. Running sudo diskwatch attributes the rest. The README notes that an exact pid per event would need fanotify with FAN_REPORT_PID or eBPF, both of which require root, so DiskWatch infers the process through a join instead.

Why does the DiskWatch Hot Files tab miss some writers?

The README states that the join is sampled every 2s, so a writer that opens, writes and closes between two samples is missed, with compilers, git and package managers named as the usual casualties. Neither inotify nor FSEvents carries a pid, so the PROCESS column is an inference over per-process byte rates and open file descriptors, not a measurement.

Does DiskWatch need smartmontools for full SMART data?

Yes for the full attribute tables. The README says smartmontools is optional but that without it the SMART tab falls back to the basic verified/failing flag. Pressing r forces a SMART refresh once the package is present.

Official sources

  1. Issues
  2. License: MIT
  3. matthart1983/diskwatch on GitHub
  4. README
  5. Releases
Community notes

Community notes