Skip to content
shellmap

List the largest directories in a tree

Find the biggest directories anywhere in a tree (not just top-level immediate children) — for tracking down where a node_modules, log dir, or build artifact bloat is hiding deep in a project.

How to list the largest directories in a tree in each shell

Bashunix
du -h . | sort -h | tail -20

Without `-s` (summary), `du` recurses into every subdirectory and prints a line per directory. `sort -h` sorts the human-readable column properly. `tail -20` keeps the 20 largest. For a depth-limit: `du -h --max-depth=3 . | sort -h | tail -20` (GNU); macOS BSD `du` uses `-d 3`. For "biggest dirs but exclude build / cache noise": `du -h --exclude=node_modules --exclude=.git . | sort -h | tail -20`.

Zshunix
du -h . | sort -h | tail -20

Same external. The interactive winners: `ncdu .` (curses UI, navigate the tree, see percentages per subdir, delete from inside the UI). `dust` (Rust rewrite, `brew install dust`) — colourised tree view with file-size bars by default.

Fishunix
du -h . | sort -h | tail -20

Same external. Fish makes capture easy: `set big_dirs (du -h . | sort -h | tail -20)`. For finding "directories over 1GB": `du -h . | awk '$1 ~ /[0-9]+G/ { print }'` (awk filters where size column ends in G).

PowerShellwindows
Get-ChildItem -Recurse -Directory | ForEach-Object { [PSCustomObject]@{ Path = $_.FullName; SizeMB = [Math]::Round((Get-ChildItem $_ -Recurse -File -ErrorAction SilentlyContinue | Measure-Object Length -Sum).Sum / 1MB, 2) } } | Sort-Object SizeMB -Descending | Select-Object -First 20

Walks every directory recursively, sums its files (recursively — so the size includes subdir contents), sorts descending, takes the top 20. SLOW on large trees because it walks the tree once per directory (O(N²) over the tree depth). For performance, install `gdu` (`scoop install gdu`) — Go-language `du` clone, parallel, ~10× faster. Or `Sysinternals\du.exe` (Microsoft's native disk-usage tool, ships separately): `du -l 3 .` shows top 3 levels.

cmd.exewindows
powershell -NoProfile -Command "Get-ChildItem -Recurse -Directory | ForEach-Object { @{Path=$_.FullName; SizeMB=[Math]::Round((Get-ChildItem $_ -Recurse -File | Measure-Object Length -Sum).Sum/1MB,2)} } | Sort-Object SizeMB -Desc | Select -First 20"

cmd has no `du`. Shell out to pwsh (above) or install via package manager. For a quick interactive option: use `wiztree.exe` (free GUI, scans an entire drive in seconds via raw NTFS access — much faster than file-walking utilities).

Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.

Gotchas & notes

  • CUMULATIVE size (this dir + all subdirs) vs IMMEDIATE-children size matters. `du -h dir` reports CUMULATIVE for `dir` itself, but the recursive output lists EACH subdir with ITS cumulative size — so a dir AND its parent both appear in the sorted list. `du --max-depth=1 dir` shows ONLY immediate children + dir itself. For a tree where "node_modules is 2GB nested inside src/feature", both `src/feature` AND `src/feature/node_modules` appear in `du -h` output.
  • On many filesystems, sparse files inflate the cumulative numbers. A 100GB-allocated-but-mostly-zero VM image consumes ~1GB on disk but appears as 100GB to `du --apparent-size`. The default `du` (no `--apparent-size`) reports DISK USAGE; `du --apparent-size` reports LOGICAL size. For "true disk pressure" analysis, use the default; for "how much would this take if I copied it elsewhere", use `--apparent-size`.
  • For HUGE trees (TB-scale filesystems), single-threaded `du` takes hours. Parallel alternatives: `gdu` (Go, parallel) is fastest cross-platform; `pdu` (Rust, parallel) is also excellent; `ncdu -1 .` saves a JSON snapshot you can re-open without re-walking. Microsoft's `du.exe` from Sysinternals is fast on Windows specifically.
  • For watching a directory shrink during a `rm -rf` or `make clean`, `watch -n 2 'du -sh dir'` shows the size every 2 seconds. pwsh equivalent: `while ($true) { (Get-ChildItem dir -Recurse -File | Measure-Object Length -Sum).Sum / 1MB; Start-Sleep 2 }`. Useful for verifying cleanup is actually progressing.

Related commands

Related tasks