Disk space problems are usually discovered late.

A database volume fills up, logs quietly grow, Docker leaves old layers around, or a backup job writes to the wrong path. At that point, du works, but it is not pleasant.

ncdu is the classic answer: scan a directory from the terminal, then browse the largest files and folders interactively.

Which ncdu Repo is This?

There is one important caveat up front.

The requested repository, rofl0r/ncdu, is an unofficial GitHub fork of ncdu and contains version 1.15.1.

The official ncdu project has continued beyond that. At analysis time, the official project page listed a newer C LTS line and a newer Zig-based stable line. The current official page describes ncdu as a text-mode disk usage analyzer for finding space-heavy directories on remote servers and POSIX-like systems.

So this post is specifically about the requested GitHub fork: a compact C/autotools/ncurses codebase that is still useful to understand how ncdu 1.x works.

What is ncdu?

ncdu means “NCurses Disk Usage”.

It is a disk usage analyzer with a terminal interface. You point it at a directory, it scans recursively, calculates disk usage and apparent size, then opens a browser where you can move through the tree, sort by size, inspect items, and delete things if you choose.

The normal usage is simple:

ncdu /var

For a whole filesystem scan, stay on one filesystem:

ncdu -x /

For safer cleanup sessions, I prefer read-only mode:

ncdu -rr /var

-r disables deletion from inside the browser. -rr also disables shell spawning, which matters if you are using ncdu on a production server over SSH and want an inspection-only session.

Why It Still Matters

ncdu is one of those tools that earns its place because it is fast to understand.

You do not need a web dashboard, database, agent, or collector. You SSH into a machine, run one command, and immediately see what is large.

That makes it useful for:

  • Finding oversized logs.
  • Inspecting Docker volumes and bind mounts.
  • Checking build caches.
  • Investigating full VPS disks.
  • Browsing remote filesystems over SSH.
  • Exporting a scan for later inspection.
  • Giving yourself a safer alternative to rm -rf guesswork.

Tech Overview

This fork is written in C and uses ncurses for the interface.

The source tree is small:

  • src/main.c parses CLI options and controls program state.
  • src/dir_scan.c walks the filesystem.
  • src/dir_mem.c builds the in-memory tree and handles hard links.
  • src/browser.c draws the ncurses browser.
  • src/dirlist.c handles sorting and visible-list navigation.
  • src/dir_export.c writes scan data as JSON.
  • src/dir_import.c reads exported JSON.
  • src/delete.c handles interactive deletion.
  • src/shell.c handles shell spawning.
  • src/exclude.c implements exclude patterns and CACHEDIR.TAG behavior.
  • doc/ncdu.pod is the manpage source.
  • deps/ contains vendored yopt and khashl.

The internal model is a tree of struct dir nodes. Each node stores disk usage, apparent size, inode, device, parent/sibling/child links, hard-link pointers, item count, flags, and a flexible filename field.

Extended mode adds file mode, uid, gid, and modification time. That is why -e is useful for audits, but the manpage notes it costs more memory and produces larger exports.

Scanning and Exporting

The scanner uses lstat() by default, so symlinks are treated carefully. With -L, ncdu can follow symlinks to files, but this 1.x code path does not follow symlinks to directories.

Useful scan flags:

ncdu -x /
ncdu --exclude '*.log' /var
ncdu -X excludes.txt /srv
ncdu --exclude-caches /home
ncdu --exclude-kernfs /

The export/import workflow is one of ncdu’s best tricks.

Export a scan:

ncdu -0 -o scan.json /srv

Open it later:

ncdu -f scan.json

Scan remotely and browse locally:

ssh -C user@server ncdu -o- /srv | ncdu -f-

That pattern is excellent when a remote server has a slow terminal connection. The remote side does the scan, the local side handles browsing, and you avoid interactive latency.

Disk usage tools differ on hard links.

This code marks files with more than one link as hard-link candidates and tracks them with a hash table keyed by device and inode. ncdu 1.7 and later improved hard-link handling so each unique inode is counted once for each directory where it appears.

That is a sensible compromise for browsing directory trees, but it still does not mean deleting a directory will always reclaim the displayed size. If another hard link exists outside the scanned tree, the underlying inode can remain allocated.

Local Build Notes

The README describes two build paths.

From a release tarball:

./configure --prefix=/usr
make
make install

From the git repository:

autoreconf -i
./configure --prefix=/usr
make

The git route requires generated autotools files, so you need autoconf/automake, pkg-config, Perl/pod2man, a C compiler, and curses development headers.

Field Note: Local Trial

I tried to validate the build on 2026-08-29.

The git clone did not include a generated configure script, and this machine did not have autoreconf.

I then downloaded the ncdu-1.15.1.tar.gz release tarball from the upstream download path. That tarball did include configure, Makefile.in, and config.h.in.

The release build still stopped because this host lacks the curses development header:

checking ncurses.h usability... no
checking ncurses.h presence... no
checking for ncurses.h... no
configure: error: required header file not found

I did not install system packages during the analysis.

A system ncdu binary was present on the machine, but it was version 1.19, not this fork’s 1.15.1, so I did not use it as proof that the requested repository built successfully.

Safer Usage Patterns

For production servers, I would start with:

ncdu -rr -x /

That means:

  • -r: no file deletion from the ncdu browser.
  • second r: no shell spawning from inside ncdu.
  • -x: do not cross filesystem boundaries.

For broad Linux scans, add pseudo-filesystem exclusion if your ncdu version supports it:

ncdu -rr -x --exclude-kernfs /

For repeatable inspections:

ncdu -0 -o /tmp/root-scan.json -x /

Then browse later:

ncdu -f /tmp/root-scan.json

Remember that imported trees disable refresh, deletion, and shell spawning because the imported file may not match the current filesystem.

When ncdu Fits

ncdu is a good fit if you want:

  • A fast terminal disk usage browser.
  • Something usable over SSH.
  • A better workflow than nested du -sh *.
  • Offline or remote scan exports.
  • A compact POSIX-oriented tool.
  • No daemon, database, web UI, or agent.

It is less ideal if you need:

  • Continuous disk monitoring.
  • Multi-host dashboards.
  • Historical storage metrics.
  • Policy-based cleanup automation.
  • Graphical treemap views.
  • Parallel scanning from this old 1.15.1 fork.

For those cases, pair ncdu with monitoring tools, or look at newer ncdu versions and alternative disk analyzers.

Alternatives to Know

The official ncdu page lists many related tools. The ones I would compare first:

  • gdu for a Go disk usage analyzer with ncdu import/export compatibility.
  • dua for a Rust CLI/TUI disk analyzer.
  • diskonaut for a terminal treemap-style view.
  • QDirStat for a graphical Qt disk usage tool.
  • GNOME Disk Usage Analyzer for a desktop GUI.

For modern ncdu itself, check the official project page before choosing this fork. The requested GitHub repo is valuable as source material, but daily users usually want their package manager or current upstream release.

Conclusion

ncdu is still the practical terminal answer to “what filled this disk?”

The rofl0r/ncdu repository is a small, readable C snapshot of ncdu 1.15.1: autotools, ncurses UI, recursive scanner, JSON export/import, hard-link tracking, exclusion rules, read-only modes, deletion, and shell integration.

The local build did not complete because this machine lacks autoreconf for the git tree and ncurses.h for the release tarball. That is a dependency issue, and it lines up with the README’s build requirements.

For most readers, install ncdu from your OS package manager or current upstream releases. For understanding the classic C implementation, this fork is compact enough to read in an afternoon.

FAQ