gdu
Disk usage analyzer with console interface
About gdu
This large README is shown as a plain-text preview. Read the full README at the source
# go DiskUsage()
<img src="./gdu.png" alt="Gdu " width="200" align="right">
[](https://codecov.io/gh/dundee/gdu)
[](https://goreportcard.com/report/github.com/dundee/gdu)
[](https://codeclimate.com/github/dundee/gdu/maintainability)
[](https://codescene.io/projects/13129)
Pretty fast disk usage analyzer written in Go.
Gdu is intended primarily for SSD disks where it can fully utilize parallel processing.
However HDDs work as well, but the performance gain is not so huge.
[](https://asciinema.org/a/382738)
<a href="https://repology.org/project/gdu/versions">
<img src="https://repology.org/badge/vertical-allrepos/gdu.svg" alt="Packaging status" align="right">
</a>
## Installation
Head for the [releases page](https://github.com/dundee/gdu/releases) and download the binary for your system.
Using curl:
curl -L https://github.com/dundee/gdu/releases/latest/download/gdu_linux_amd64.tgz | tar xz
chmod +x gdu_linux_amd64
mv gdu_linux_amd64 /usr/bin/gdu
See the [installation page](./INSTALL.md) for other ways how to install Gdu to your system.
Or you can use Gdu directly via Docker:
docker run --rm --init --interactive --tty --privileged --volume /:/mnt/root ghcr.io/dundee/gdu /mnt/root
## Usage
```
gdu [flags] [directory_to_scan...]
Flags:
--archive-browsing Enable browsing of zip/jar/tar archives (tar, tar.gz, tar.bz2, tar.xz)
--collapse-path Collapse single-child directory chains
--config-file string Read config from file (default is $HOME/.gdu.yaml)
--ctrl-c-quits Quit gdu when Ctrl+C is pressed during a scan instead of stopping the scan and keeping results (Esc always stops the scan)
-D, --db string Store analysis in database (*.sqlite for SQLite, *.badger for BadgerDB)
--depth int Show directory structure up to specified depth in non-interactive mode (0 means the flag is ignored); also limits entries inside browsed archives
--enable-profiling Enable collection of profiling data and provide it on http://localhost:6060/debug/pprof/
-E, --exclude-type strings File types to exclude (e.g., --exclude-type yaml,json)
-L, --follow-symlinks Follow symlinks for files, i.e. show the size of the file to which symlink points to (symlinks to directories are not followed)
-h, --help help for gdu
-i, --ignore-dirs strings Paths to ignore (separated by comma). Can be absolute or relative to current directory (default [/proc,/dev,/sys,/run])
-I, --ignore-dirs-pattern strings Path patterns to ignore (separated by comma)
-X, --ignore-from string Read path patterns to ignore from file
-G, --ignore-from-gitignore string Read directories to ignore from file with .gitignore-style patterns
-f, --input-file string Import analysis from JSON file
--interactive Force interactive mode even when output is not a TTY
-l, --log-file string Path to a logfile (default "/dev/null")
--max-age string Include files with mtime no older than DURATION (e.g., 7d, 2h30m, 1y2mo)
-m, --max-cores int Set max cores that Gdu will use. 8 cores available (default 8)
--min-age string Include files with mtime at least DURATION old (e.g., 30d, 1w)
--mouse Use mouse
-c, --no-color Do not use colorized output
--no-confirm-quit Do not ask for confirmation before quitting after a long scan
-x, --no-cross Do not cross filesystem boundaries
--no-delete Do not allow deletions
-H, --no-hidden Ignore hidden directories (beginning with dot)
--no-prefix Show sizes as raw numbers without any prefixes (SI or binary) in non-interactive mode
-p, --no-progress Do not show progress in non-interactive mode
--no-spawn-shell Do not allow spawning shell
-u, --no-unicode Do not use Unicode symbols (for size bar)
--no-view-file Do not allow viewing file contents
-n, --non-interactive Do not run in interactive mode
--output-attrs string Export only selected JSON attributes (name,asize,dsize,items,mtime,notreg,ino)
-o, --output-file string Export all info into file as JSON
-r, --read-from-storage Use existing database instead of re-scanning
--reverse-sort Reverse sorting order (smallest to largest) in non-interactive mode
--sequential Use sequential scanning (intended for rotating HDDs)
-A, --show-annexed-size Use apparent size of git-annex'ed files in case files are not present locally (real usage is zero)
-a, --show-apparent-size Show apparent size
-d, --show-disks Show all mounted disks
-k, --show-in-kib Show sizes in KiB (or kB with --si) in non-interactive mode
-C, --show-item-count Show number of items in directory
-M, --show-mtime Show latest mtime of items in directory
-B, --show-relative-size Show relative size
--show-symlink-target Show symlink target (name -> target) in the file list
--si Show sizes with decimal SI prefixes (kB, MB, GB) instead of binary prefixes (KiB, MiB, GiB)
--since string Include files with mtime >= WHEN. WHEN accepts RFC3339 timestamp (e.g., 2025-08-11T01:00:00-07:00) or date only YYYY-MM-DD (calendar-day compare; includes the whole day)
-s, --summarize Show only a total in non-interactive mode
-t, --top int Show only top X largest files in non-interactive mode
--trash-command string Command used to move items to trash instead of the built-in trash (e.g. 'trash-put --trash-dir ~/mytrash')
-T, --type strings File types to include (e.g., --type yaml,json)
--until string Include files with mtime <= WHEN. WHEN accepts RFC3339 timestamp or date only YYYY-MM-DD
-v, --version Print version
--web Run the web UI (serves a browser interface instead of the terminal UI)
--web-listen string Address for the web UI to listen on (default: localhost with a random free port)
--web-open Open the web UI in the default browser on start (default true)
--write-config Write current configuration to file (default is $HOME/.gdu.yaml)
Basic list of actions in interactive mode (show help modal for more):
↑ or k Move cursor up
↓ or j Move cursor down
→ or Enter or l Go to highlighted directory
← or h Go to parent directory
d Delete the selected file or directory
D Move the selected file or directory to trash
e Empty the selected directory
n Sort by name
s Sort by size
c Show/hide item count
? Show help modal
```
## Examples
gdu # analyze current dir
gdu -a # show apparent size instead of disk usage
gdu --no-delete # prevent write operations
gdu --no-view-file # prevent viewing file contents
gdu --trash-command 'trash-put --trash-dir ~/mytrash' # use own trash command for the D key
gdu --trash-command 'mv -f "$1" ~/mytrash/' # trash by moving items with mv
gdu <some_dir_to_analyze> # analyze given dir
gdu dir_a dir_b dir_c # analyze several dirs at once
gdu -d # show all mounted disks
gdu -l ./gdu.log <some_dir> # write errors to log file
gdu -i /sys,/proc / # ignore some paths
gdu -I '.*[abc]+' # ignore paths by regular pattern
gdu -X ignore_file / # ignore paths by regular patterns from file
gdu -G .gitignore / # ignore dirs by .gitignore-style patterns from file
gdu -c / # use only white/gray/black colors
gdu -n / # only print stats, do not start interactive mode
gdu --interactive / | tee out.txt # force interactive mode even when stdout is piped
gdu -p / # do not show progress, useful when using its output in a script
gdu -ps /some/dir # show only total usage for given dir
gdu -t 10 / # show top 10 largest files
gdu --reverse-sort -n / # show files sorted from smallest to largest in non-interactive mode
gdu / > file # write stats to file, do not start interactive mode
gdu -o- / | gzip -c >report.json.gz # write all info to JSON file for later analysis
zcat report.json.gz | gdu -f- # read analysis from file
gdu --db=tmp.badger / # use persistent key-value storage for saving analysis data
gdu --db=tmp.db / # use persistent SQLite storage for saving analysis data
gdu -r / # read saved analysis data from persistent key-value storage
gdu --web / # analyze and browse the results in a web browser
gdu --web --web-listen localhost:8080 / # serve the web UI on a fixed address
gdu --web --web-open=false / # print the URL but do not open a browser
## Scanning multiple directories
More than one directory can be given on the command line, which is useful when only a subset of a large directory is of interest:
gdu ~/projects/alpha ~/projects/beta ~/projects/gamma
The directories are scanned one after another and presented together under a virtual top level directory named `(multiple)`, so they can be compared and sorted like ordinary siblings. They are listed by their absolute path, so directories that share a base name stay distinguishable. Each of them keeps its real path, so rescanning, deletion and opening a shell work as usual once you navigate into one of them.
The virtual top level directory itself has no counterpart on disk, so operations that need a real path are unavailable while it is shown: `--change-cwd`, spawning a shell, browsing to the parent directory (`--browse-parent-dirs`) and exporting to JSON. Rescanning it rescans every directory below it.
Directories that are nested in one another are rejected, since scanning both would count the nested part twice. Exporting (`-o`) and database storage (`--db`) accept a single directory only.
## Modes
Gdu has three modes: interactive (default), non-interactive and export.
Non-interactive mode is started automatically when TTY is not detected (using [go-isatty](https://github.com/mattn/go-isatty)), for example if the output is being piped to a file, or it can be started explicitly by using a flag. Use `--interactive` to disable this automatic fallback and force interactive mode.
In non-interactive mode (and without `--top` and `--depth` flags), gdu uses a memory-efficient analyzer that only tracks top-level directory totals.
This means memory usage stays constant regardless of how large the scanned directory tree is.
When `--top` or `--depth` flags are used, the full directory tree is built in memory as in interactive mode.
Export mode (flag `-o`) outputs all usage data as JSON, which can be later opened using the `-f` flag. In interactive mode, press `Esc` or `Ctrl+C` during a scan to stop scheduling new work and keep the results found so far; pressing `Ctrl+C` again while the scan is stopping quits gdu. If you would rather have the first `Ctrl+C` quit gdu outright, use `--ctrl-c-quits`; `Esc` keeps working either way.
By default the export includes every attribute, and directories always carry their `asize`, `dsize`, and `items` summary stats so they can be preserved on import. Use `--output-attrs=asize,dsize` to emit only selected optional attributes; `name` is always included. Available attributes are `asize`, `dsize`, `items`, `mtime`, `notreg`, and `ino`.
Gdu honors `BLOCK_SIZE` and `BLOCKSIZE` in terminal output. `BLOCK_SIZE` takes precedence; both accept GNU coreutils block-size values such as `1K`, `kB`, `human-readable`, and `si`. Explicit size-format flags override these environment variables. Exported JSON always retains raw byte values.
Hard links are counted only once.
## Web UI
Gdu can serve a browser-based interface instead of the terminal UI. Run:
```
gdu --web /some/dir
```
Gdu scans the directory, prints the URL, and (by default) opens it in your
default browser. The interface shows an animated donut chart of the current
directory's contents alongside a sortable table with size bars, breadcrumb
navigation, and a disk-usage/apparent-size toggle. Switch to the full-window
treemap to explore the complete nested subtree, select files or directories,
and double-click a directory to open it. Details too small to display are
folded into their nearest visible parent directory. Scan progress is streamed
live while the analysis runs.
In the treemap, press `O` to reveal the selected item in the system file
manager, `D` (or `Delete`) to permanently delete it after confirmation, or `?`
to show the keyboard shortcuts. In the donut view, each row of the table has
its own reveal and delete buttons that act on that item; deletion asks for
confirmation with the same dialog. The deletion dialog can suppress further
confirmations for the current browser session, for both the treemap and the
table, so with "permanent" chosen a single click on a row's delete button
deletes immediately. The `--no-delete` flag and
filtered-scan deletion restrictions apply to the web UI as well as the
terminal UI. Reveal remains available with `--no-delete` because it does not
modify scanned data. To deliberately allow deletion while filters are active,
set `GDU_ALLOW_DELETE_WITH_FILTER=1`; the displayed tree may then omit files
that are still present on disk.
By default the server binds to `localhost` on a random free port. Use
`--web-listen` (or the `web.listen` config option) to pin a fixed address.
The compiled web assets are embedded in the binary, so no extra files or network
access are required.
**Security:** browsing is read-only and requires no authentication, so anyone
who can reach the port sees file names and sizes - keep it bound to
`localhost` (the default). Reveal and delete actions need more: a request
that both originates from a loopback address and carries a random token,
generated fresh for each server run and never served over the API. The URL is
printed to this process's terminal and passed to the configured browser
launcher. On Linux, a cold-started browser may retain that URL in its
world-readable command line; custom browser commands may do the same on any
platform. On a multi-user machine, use `--web-open=false` and open the printed
URL from an already-running browser. Pages on another origin or browser tab
are rejected even if they can reach the port. Binding to a non-loopback address
makes scan details reachable by other hosts on the network and prints a
warning.
## File flags
Files and directories may be prefixed by a one-character
flag with following meaning:
* `!` An error occurred while reading this directory.
* `.` An error occurred while reading a subdirectory, size may be not correct.
* `@` File is symlink or socket. Symlinks can be shown as `name -> target` (the link target is displayed next to the name, like `ls -l`).
* `H` Same file was already counted (hard link).
* `e` Directory is empty.
## Configuration file
Gdu can read (and write) YAML configuration file.
`$HOME/.config/gdu/gdu.yaml` and `$HOME/.gdu.yaml` are checked for the presence of the config file by default.
See the [full list of all configuration options](configuration.md).
### Examples
* To configure gdu to permanently run in gray-scale color mode:
```
echo "no-color: true" >> ~/.gdu.yaml
```
* To set default sorting in configuration file:
```
sorting:
by: name // size, name, itemCount, mtime
order: desc
```
* To configure gdu to set CWD variable when browsing directories:
```
echo "change-cwd: true" >> ~/.gdu.yaml
```
* To configure the web UI (bind address and browser behavior):
```
web:
listen: "localhost:8080" # empty (default) = localhost + random free port
open-browser: true # open the default browser on start
browser: "" # override launcher command; empty = OS default
```
* To save the current configuration
```
gdu --write-config
```
## Styling
There are wide options for how terminals can be colored.
Some gdu primitives (like basic text) adapt to different color schemas, but the selected/highlighted row does not.
If the default look is not sufficient, it can be changed in configuration file, e.g.:
```
style:
selected-row:
text-color: black
background-color: "#ff0000"
marked:
text-color: white
background-color: "#6600cc"
```
## Deletion in background and in parallel (experimental)
Gdu can delete items in the background, thus not blocking the UI for additional work.
To enable:
```
echo "delete-in-background: true" >> ~/.gdu.yaml
```
Directory items can be also deleted in parallel, which might increase the speed of deletion.
To enable:
```
echo "delete-in-parallel: true" >> ~/.gdu.yaml
```
## Saving analysis data to database
Gdu can store the analysis data to a database file instead of just memory.
This allows you to save and reload analysis results later.
Both SQLite and BadgerDB are supported.
```
gdu --db analysis.sqlite / # saves analysis data to SQLite database
gdu --db analysis.badger / # saves analysis data to BadgerDB
gdu -r --db analysis.sqlite / # reads saved data, does not run analysis again
```
## Running tests
make install-dev-dependencies
make test
## Profiling
Gdu can collect profiling data when the `--enable-profiling` flag is set.
The data are provided via embedded http server on URL `http://localhost:6060/debug/pprof/`.
You can then use e.g. `go tool pprof -web http://localhost:6060/debug/pprof/heap`
to open the heap profile as SVG image in your web browser.
## Benchmarks
Benchmarks were performed on 90G directory (100k directories, 400k files) on 500 GB SSD using [hyperfine](https://github.com/sharkdp/hyperfine).
See `benchmark` target in [Makefile](Makefile) for more info.
### Cold cache
Filesystem cache was cleared using `sync; echo 3 | sudo tee /proc/sys/vm/drop_caches`.
| Command | Mean [s] | Min [s] | Max [s] | Relative |
|:---|---:|---:|---:|---:|
| `diskus ~` | 4.489 ± 0.020 | 4.449 | 4.516 | 1.00 |
| `gdu -npc ~` | 4.716 ± 0.342 | 4.109 | 5.337 | 1.05 ± 0.08 |
| `GOMAXPROCS=80 gdu -npc ~` | 4.901 ± 1.953 | 3.627 | 9.993 | 1.09 ± 0.44 |Frequently Asked Questions
What is gdu?
gdu is a File Handling library for the Go programming language. Disk usage analyzer with console interface
How many GitHub stars does gdu have?
gdu has 6,102 GitHub stars in the directory's latest synchronization.
How do I install gdu?
Install gdu with the Go module system using `go get dundee/gdu`. Check the repository for the current installation instructions.
What category does gdu belong to?
gdu is listed under File Handling, specifically File Handling.