The first time I ran locate on a server after being used to find, the speed difference genuinely surprised me — a search across the entire filesystem came back in what felt like milliseconds instead of the many seconds find needed to walk every directory. That speed comes from a trade-off worth understanding properly: locate isn’t searching your filesystem live, it’s searching a prebuilt index. That index can go stale, and knowing exactly when and why is the difference between using locate confidently and being burned by it once. This guide covers locate from installation through daily use to its internals.
What Is the locate Command?
locate searches a prebuilt database of file names for a given pattern and reports matches almost instantly, because it never touches the live filesystem during the search itself — it just reads an indexed database file. The database is built and refreshed by a companion tool called updatedb, typically run automatically on a schedule (commonly daily, via cron or a systemd timer).
Two implementations are common in the wild today: the older mlocate, and the newer, faster plocate (which has become the default on recent Ubuntu releases and several other distributions). Both provide the same locate/updatedb command names and largely compatible behavior, with plocate offering substantially better performance and a smaller database footprint via more efficient indexing.
locate is not installed by default on many minimal Linux installations and container images — it typically needs to be installed explicitly:
$ sudo apt install plocate # Debian/Ubuntu, modern default
$ sudo apt install mlocate # Debian/Ubuntu, older alternative
$ sudo dnf install mlocate # Fedora/RHEL
$ sudo pacman -S mlocate # Arch Linux
Basic Syntax
locate [OPTIONS] PATTERN...
A Basic Example
$ locate bashrc
/etc/bash.bashrc
/etc/skel/.bashrc
/home/ubuntu/.bashrc
/root/.bashrc
/usr/share/dot.bashrc
Notice this instantly returned every file anywhere on the filesystem containing “bashrc” in its path — not just in one directory, but system-wide, because the database itself is built by indexing the whole filesystem (subject to configured exclusions).
Full Parameter Reference
| Option | Long Form | Description |
|---|---|---|
-i | --ignore-case | Case-insensitive matching |
-c | --count | Print only the number of matches, not the matches themselves |
-n LIMIT | --limit=LIMIT | Stop after LIMIT matches |
-r REGEX | --regexp=REGEX | Interpret the pattern as a basic regular expression instead of a glob-like substring match |
--regex | Interpret all given patterns as extended regular expressions | |
-b | --basename | Match only against the base filename, not the full path |
-e | --existing | Only print entries for files that still exist on disk (checked at query time) |
-w | --wholename | Match against the full path (this is the default behavior) |
-0 | --null | Separate results with a NUL byte instead of a newline, safe for piping into xargs -0 |
-S | --statistics | Print statistics about the database (mlocate; not supported identically in plocate) |
-d PATH | --database=PATH | Use an alternate database file instead of the default |
-A | --all | Require all patterns to match (when multiple patterns given) |
Case-Insensitive Search with -i
$ locate -i BASHRC
/etc/bash.bashrc
/etc/skel/.bashrc
/home/ubuntu/.bashrc
Counting Matches with -c
$ locate -c bashrc
6
Useful in scripts where you only need to know how many matches exist rather than enumerate them.
Limiting Results with -n
$ locate -n 3 .conf
/etc/adduser.conf
/etc/ca-certificates.conf
/etc/debconf.conf
Handy when a pattern is broad and you just want a quick sample rather than a flood of thousands of paths.
Regular Expression Matching with -r
$ locate -r '\.bashrc$'
/etc/bash.bashrc
/etc/skel/.bashrc
/home/ubuntu/.bashrc
/root/.bashrc
/usr/share/dot.bashrc
/usr/share/base-files/dot.bashrc
This anchors the match specifically to filenames ending in .bashrc, which is more precise than the default substring behavior — without the anchor, “bashrc” would also match things like bashrc.bak or mybashrc_old.
How locate Works Internally
locate‘s speed comes entirely from separating the expensive part of the work (walking the filesystem) from the cheap part (searching an index). Here’s the division of labor:
updatedb does the expensive work. It walks the entire filesystem (subject to configured exclusions in /etc/updatedb.conf, such as network filesystems, temp directories, and other paths you don’t want indexed), collects every path it finds, and writes them into a compact, typically sorted and often compressed database file — on mlocate/plocate systems, this lives at /var/lib/mlocate/mlocate.db or /var/lib/plocate/plocate.db respectively. This process can take anywhere from seconds to minutes depending on filesystem size, and is normally scheduled to run automatically once a day via cron (/etc/cron.daily/locate or similar) or a systemd timer (plocate-updatedb.timer).
locate does the cheap work. It opens the prebuilt database and searches it, which for plocate specifically uses a posting-list index structure (similar in spirit to search-engine indexing) that lets it skip large portions of the database that can’t possibly match, making searches extremely fast even against databases covering millions of files. Because it’s just scanning/searching an already-built structure rather than touching the actual filesystem, there’s no directory traversal, no stat() calls per file, and no permission-check overhead during the search itself (permission filtering, where it applies, is handled separately — see security below).
This division is exactly why locate is fast but potentially stale: a file created five minutes ago won’t appear in locate results until the next updatedb run indexes it — a difference in kind from find, which is always looking at the live filesystem in real time, and consequently always accurate but slower.
Manually Refreshing the Database
If you need up-to-date results right now rather than waiting for the scheduled run:
$ sudo updatedb
This rebuilds the database from scratch, respecting the exclusion rules in /etc/updatedb.conf. On a large filesystem this can take a noticeable amount of time and I/O, so it’s not something you want to run casually in a tight loop — for genuinely live results, find is the better tool despite being slower per-call.
Real-World Use Cases
1. Quickly Finding Where a Package Installed Its Files
$ locate nginx.conf
2. Checking for Leftover Files After Uninstalling Software
$ locate -i oldapp
3. Auditing for a Specific File Type System-Wide
$ locate -r '\.pem$'
4. Feeding Results Into Another Command Safely
$ locate -0 -r '\.log$' | xargs -0 ls -la
Using -0 and xargs -0 together correctly handles filenames containing spaces or unusual characters, avoiding a classic pipeline bug.
5. Verifying a File Genuinely Still Exists Before Acting on a Stale Result
$ locate -e config.yaml
The -e flag filters out database entries for files that have since been deleted, at the cost of a stat() call per candidate match — a good middle ground between raw database speed and full accuracy.
Shell Scripting and Automation
A script that finds and reports any world-writable configuration files system-wide, using locate for speed and find-style checks for the actual permission verification:
#!/bin/bash
# find_writable_configs.sh - flag world-writable .conf files quickly
set -euo pipefail
locate -0 -r '\.conf$' | while IFS= read -r -d '' f; do
if [[ -e "$f" ]] && [[ $(stat -c '%a' "$f" 2>/dev/null) =~ [2367]$ ]]; then
echo "World-writable: $f"
fi
done
This pattern — using locate to quickly narrow down candidates system-wide, then applying more expensive per-file checks only to the (much smaller) candidate list — is a common and effective way to combine locate‘s speed with find‘s precision.
locate vs Related Commands
| Command | Purpose |
|---|---|
locate | Extremely fast filename search against a prebuilt, periodically-refreshed database |
find | Real-time, always-accurate filesystem search with rich filtering (size, time, permissions, type) |
which | Locates executables specifically, searching $PATH |
whereis | Locates binaries/source/manuals in standard system directories |
grep -r | Searches file contents, not filenames, by walking the filesystem live |
fd | A modern, user-friendly alternative to find, not database-backed, but much faster than classic find for typical interactive use |
The core trade-off to internalize: locate is fast but potentially stale; find is slower but always current. For anything involving files created or deleted very recently, or for exhaustive correctness (security audits, verifying a deletion happened), use find. For everyday “where is that file” convenience queries, locate wins on speed by a wide margin.
Troubleshooting Common Issues
Problem: locate somefile returns nothing even though the file definitely exists. The most common cause by far: the database hasn’t been updated since the file was created. Run sudo updatedb and try again. Also check whether the file lives in a path excluded by /etc/updatedb.conf (network mounts and certain temp directories are commonly excluded by default).
Problem: locate isn’t installed at all. Neither mlocate nor plocate ships by default on many minimal distributions or container base images. Install one explicitly (see the installation commands above).
Problem: locate shows files a non-privileged user shouldn’t be able to see. Both mlocate and plocate are designed to respect filesystem permissions when the database is built with the setgid helper correctly configured — results are filtered against the querying user’s actual read permissions at query time. If this filtering seems not to be working as expected, verify the installed package’s setup and permissions on the database file itself (ls -l /var/lib/plocate/plocate.db), since a misconfigured install can undermine this protection.
Problem: updatedb takes a very long time or heavily loads I/O when it runs. This is expected on very large filesystems, especially the first run. Check /etc/updatedb.conf for PRUNEPATHS and PRUNEFS settings to exclude directories (build caches, huge data directories, network filesystems) that don’t need indexing, which meaningfully speeds up subsequent runs.
Performance Optimization
plocate‘s posting-list index format is substantially faster and more space-efficient than the oldermlocateformat, especially on databases covering millions of files — prefer it where available.- Exclude high-churn, high-volume, or irrelevant directories (build artifacts,
/tmp, network mounts, container overlay filesystems) via/etc/updatedb.conf‘sPRUNEPATHS/PRUNEFSto keep both the database size andupdatedbruntime manageable. - Avoid running
updatedbmanually in a tight loop or as part of frequent automation — it’s meant for periodic (typically daily) refresh, not real-time indexing. If you need real-time accuracy, usefindfor that specific query instead of forcing a database rebuild. - For extremely large filesystems, consider whether indexing everything is even necessary — scoping
updatedb‘s coverage to relevant top-level directories can meaningfully cut both database size and query time.
Security Implications
locate‘s permission-aware filtering (present in properly configured mlocate/plocate installs) is specifically designed to prevent unprivileged users from discovering the existence and paths of files they don’t have permission to read — for example, another user’s private files, or files inside a restricted directory. This matters because even just knowing a file’s path and name can leak sensitive information (a filename might reveal a project codename, a person’s identity, or the existence of a security-sensitive configuration) even without reading its contents.
If you administer a multi-user system, verify that the locate database’s permission-filtering setgid mechanism is functioning as intended rather than assuming it “just works” — a misconfigured installation can expose a system-wide file listing to any local user, which is a meaningful information-disclosure risk, particularly on shared servers. Running updatedb as root without the intended privilege-drop configuration is a common way this protection gets accidentally bypassed.
Compatibility Across Distributions
Recent Ubuntu releases (22.04 and later) default to plocate when the “locate” functionality is installed, as do several other modern distributions moving away from the older mlocate. RHEL, CentOS Stream, and Fedora typically ship mlocate, though plocate is available in most repositories as an alternative. The core locate command-line interface and most common flags (-i, -c, -n, -r) behave consistently across both implementations, but implementation-specific flags like mlocate‘s -S/--statistics are not guaranteed to be present or behave identically in plocate — check locate --help on your specific system before relying on less common flags.
Best Practices
- Install
plocatewhere available for meaningfully better performance over legacymlocate. - Run
sudo updatedbmanually when you need results for very recently created files and can’t wait for the next scheduled refresh. - Use
findinstead oflocatewhenever real-time accuracy matters more than speed — security audits, verifying deletions, or querying freshly-created files. - Tune
/etc/updatedb.confto exclude irrelevant or sensitive high-churn directories, both for performance and to avoid indexing things that don’t need to be searchable. - On multi-user systems, verify permission-aware filtering is genuinely working rather than assuming it by default.
Summary
locate trades real-time accuracy for dramatic speed by searching a prebuilt, periodically refreshed database instead of walking the live filesystem on every query. That trade-off makes it the right tool for quick, everyday “where is this file” lookups across an entire system, while find remains the right tool whenever you need guaranteed up-to-date or richly filtered results. Understanding the updatedb refresh cycle — and knowing to trigger it manually when needed — is really the only prerequisite to using locate confidently.
References
- plocate Project Documentation — https://plocate.sesse.net/
- mlocate man pages — https://man7.org/linux/man-pages/man1/mlocate.1.html
- Linux man-pages project:
man 1 locate— https://man7.org/linux/man-pages/man1/locate.1.html - Ubuntu Manpage Repository:
updatedb.conf— https://manpages.ubuntu.com/manpages/noble/en/man5/updatedb.conf.5.html
