The find command walks a directory tree and acts on files that match your criteria. By default it descends into every subdirectory, no matter how deep. That’s often more than you want. Three options give you control over how deep find goes and in what order it reports results:
-maxdepth— how far down to descend-mindepth— how far down to start matching-depth— process a directory’s contents before the directory itself
They sound similar but do very different things. This article explains each one, the depth-numbering model they share, and the gotchas that trip people up.
Table of Contents
The depth model: what “level” means
find assigns every path a depth number relative to the starting point:
| Depth | What it refers to |
|---|---|
0 | The starting point(s) you pass to find (e.g. . or /var/log) |
1 | Files and directories directly inside the starting point |
2 | Items one level deeper |
n | Items n levels below the start |
So given this tree, started with find .:
. <- depth 0
├── a.txt <- depth 1
├── docs <- depth 1
│ ├── b.txt <- depth 2
│ └── sub <- depth 2
│ └── c.txt <- depth 3
Both -maxdepth and -mindepth take an integer that refers to these levels.
Portability note:
-maxdepth,-mindepth, and-depthare all standard in GNU findutils (Linux). On BSD/macOSfind,-maxdepth/-mindepthexist too, and-depthalso accepts an optional numeric argument (-depth n) that GNUfinddoes not support. This article focuses on GNU/Linux behavior.
-maxdepth: limit how deep find descends
-maxdepth n tells find to descend at most n levels below the starting points. It’s the option you reach for most often.
Only the immediate contents (depth 1), no recursion:
find . -maxdepth 1
Match .log files in the current directory but not in subdirectories:
find . -maxdepth 1 -name '*.log'
Search the current directory and one level of subdirectories:
See also: Mastering the Linux Command Line — Your Complete Free Training Guide
find . -maxdepth 2 -type f
-maxdepth 0 means “only process the starting points themselves” — useful for testing a test/expression against exactly the arguments you passed:
find /etc/hostname /etc/hosts -maxdepth 0 -type f
Performance bonus: -maxdepth actually prunes the traversal — find never descends into deeper directories, so on huge trees it’s far faster than filtering after the fact.
-mindepth: skip the shallow levels
-mindepth n does the opposite: it ignores everything above level n and only applies your tests at level n and below.
Skip the starting directory itself but match everything below it:
find . -mindepth 1
This is the classic way to say “the contents, but not the folder I started from.”
Match files that live at least two levels deep (i.e., inside a subdirectory, never directly in the top folder):
find . -mindepth 2 -type f
A very common real-world use is deleting a directory’s contents while keeping the directory itself:
find /tmp/cache -mindepth 1 -delete
Without -mindepth 1, find would also match /tmp/cache (depth 0) and try to delete it too.
Combining -mindepth and -maxdepth: target an exact band
Use both to match a specific range of levels. To act on items that are exactly two levels deep:
find . -mindepth 2 -maxdepth 2 -type d
That lists directories at depth 2 and nowhere else — great for iterating over a fixed layout like year/month/ or namespace/service/.
Levels 2 through 4 only:
find . -mindepth 2 -maxdepth 4 -name '*.conf'
-depth: a different meaning entirely
Here’s the biggest source of confusion: -depth is not about depth numbers at all. It’s not -maxdepth without the “max.”
-depth changes the traversal order. Normally find reports a directory before the files inside it (pre-order). With -depth, find processes a directory’s contents first, then the directory itself (post-order, depth-first).
Compare. Default order:
$ find docs
docs
docs/b.txt
docs/sub
docs/sub/c.txt
With -depth:
$ find docs -depth
docs/b.txt
docs/sub/c.txt
docs/sub
docs
Notice the directory docs now comes last.
Why -depth matters
The main use case is any operation where acting on a directory before its contents would be wrong — most obviously deleting a tree. You can’t remove a directory until it’s empty, so you must process children first:
find /tmp/build -depth -type d -empty -delete
In fact, -delete implies -depth automatically, so you rarely type it yourself for deletions. But it’s essential when you’re piping to another command or doing custom -exec logic that mutates directories.
Renaming/normalizing directory names bottom-up is another case: if you rename parent directories first, the child paths you were about to touch no longer exist. -depth avoids that by handling children before parents.
-maxdepth/-mindepth vs -depth: side by side
| Option | Controls | Takes a number? | Affects traversal speed? |
|---|---|---|---|
-maxdepth n | Deepest level to descend to | Yes | Yes — prunes the tree |
-mindepth n | Shallowest level to match | Yes | No — still walks everything above |
-depth | Order (contents before container) | No (in GNU find) | No |
Key mental model:
-maxdepth/-mindepth= which levels are in play.-depth= which order things are visited.
Common gotchas
1. Put -maxdepth/-mindepth early in the expression. GNU find warns if these “global options” appear after tests, because they apply to the whole command regardless of position:
# Works but triggers a warning:
find . -name '*.log' -maxdepth 1
# Preferred:
find . -maxdepth 1 -name '*.log'
2. -depth is not -maxdepth. If you meant “don’t go deep,” you want -maxdepth. -depth alone still traverses the entire tree — it only reorders output.
3. -maxdepth 0 targets the arguments, not “no depth.” It matches the starting points themselves. Handy for validating inputs.
4. -prune is the other pruning tool. -maxdepth limits by level; -prune skips specific named subtrees (e.g. avoid node_modules). They solve different problems and often combine.
5. Mixing -depth with -prune doesn’t work as expected. -prune has no effect when -depth (or -delete) is in play, because by the time find reaches a directory in post-order, it has already descended into it.
Quick reference
# Only the current directory, no recursion
find . -maxdepth 1 -type f
# Everything below the start, but not the start itself
find . -mindepth 1
# Exactly one specific level (depth 3)
find . -mindepth 3 -maxdepth 3
# A range of levels
find . -mindepth 2 -maxdepth 4 -name '*.conf'
# Empty the directory but keep it
find /tmp/cache -mindepth 1 -delete
# Post-order (children first) — needed for safe directory deletion
find /tmp/build -depth -type d -empty -delete
Bottom line
- Use
-maxdepthto stopfindfrom going too deep (and to speed it up). - Use
-mindepthto ignore the shallow levels and target items further down. - Combine both to isolate an exact band of levels.
- Use
-depthonly when order matters — process contents before their container, which is why deletions rely on it.
Remember the one-liner: -maxdepth/-mindepth decide which levels; -depth decides what order.


