Linux command: locate
You need a file and you know its name, but not where it lives. It could be anywhere on a server with millions of files. You could walk the whole disk with find and wait, or you could ask a tool that already knows where everything is and answers before you finish typing. That tool is locate. It does not search the disk at all; it looks the answer up in an index, and that is why it feels instant.
1. The Basics
The job of locate is to find files by name across the whole system, fast. You give it a piece of a name, and it prints every path that contains that piece:
$ locate hosts
/etc/hosts
/etc/hosts.allow
/etc/hosts.deny
The single idea that makes locate different from every other search tool is this: it does not look at the live filesystem. Instead, a background job scans the disk once a day and writes every path into a compact database. When you run locate, it reads that database, never the disk. Searching a prepared index is thousands of times faster than walking directories, which is why the answer comes back the instant you press Enter.
That speed comes with one honest trade-off: the database is only as fresh as its last update. A file created five minutes ago is usually not in it yet, and a file deleted this morning may still be listed. For most searches this does not matter, because you are looking for things that have existed for a while, config files, logs, libraries, photos.
locate does not find files; it looks them up. It answers from a daily index, not from the disk in front of you.
Back to topThe right mental model:
locateis a card catalog, andfindis walking the shelves. The catalog answers in a second but was printed last night. Walking the shelves is slower but shows you exactly what is there right now. Reach for the catalog first, and only walk the shelves when you need this-second accuracy.
2. Where the Name Comes From
Like find, the name locate is not an acronym or a joke. It is the plain English verb for the task: to locate a file. The early Unix authors preferred short, ordinary words for ordinary jobs, and this was as short as the word gets.
The interesting part is the letter in front of it. On a modern Linux system the command you run is almost never called plain locate; it is one of a family whose single-letter prefix records the tool's history:
| Name | Prefix stands for | What it added |
|---|---|---|
locate |
(the original) | The first index-based file finder |
slocate |
secure | Hides files the user is not allowed to see |
mlocate |
merging | Reuses the old index, updating only what changed |
plocate |
posting-list | A trigram index that is dramatically faster |
So when you type locate today, you are almost certainly running plocate or mlocate under that friendly name. Each prefix marks a step forward: first make it secure, then make the daily update cheap, then make the search itself blazing fast. Reading the prefix is reading the changelog.
3. A Short History
The idea behind locate is older than most of the tools around it. It was written by James A. Woods in the early 1980s and described in a short paper about finding files quickly. His insight was simple and lasting: instead of searching the disk every time, build one compressed index of all filenames and search that. He also invented a clever compression, storing only the difference between each path and the one before it, so the whole filesystem's names fit in a small file.
That original locate travelled with BSD Unix and later became part of GNU findutils, the same package that ships find. Over the decades it was reinvented three times, each version keeping the same idea but fixing a real problem:
| Era | Milestone |
|---|---|
| early 1980s | James A. Woods writes the first locate: a compressed index of every filename, searched instead of the disk |
| BSD / GNU | locate and updatedb ship with BSD and then with GNU findutils |
| late 1990s | slocate (secure locate) adds permission checks so users only see files they may read |
| mid 2000s | mlocate (merging locate) reuses the old database and re-scans only changed directories, making the daily update fast |
| 2020 | plocate by Steinar H. Gunderson introduces a trigram index; searches that took a second now take a millisecond |
| Today | plocate is the default on Debian and Ubuntu; mlocate remains common on older and other systems |
The slocate step is worth pausing on. The very first locate had a privacy hole: because it read from one shared index built by root, any user could see the names of files anywhere on the system, even in folders they could not open. slocate, and every version since, fixed this by checking each result against the caller's own permissions. This is why locate can safely run on a shared server today.
The version on this article's reference system is plocate 1.1.19. It is deliberately not compatible with the old BSD locate database format, and it assumes UTF-8; in exchange it is far faster than everything before it. The commands below are written for it, and note where mlocate behaves differently.
Installing it. On many systems locate is already there, but if it is missing, the package is named after the implementation, usually plocate:
$ sudo apt install plocate # Debian, Ubuntu
$ sudo dnf install plocate # Fedora
$ sudo pacman -S plocate # Arch Linux
After installing, run sudo updatedb once to build the first database. From then on the daily timer keeps it current, and the plain command locate resolves to whichever implementation you installed.
4. Simple Use Cases
4.1 The Simplest Possible Use
Give locate a word, and it prints every path in the database that contains that word anywhere:
$ locate sshd_config
/etc/ssh/sshd_config
/usr/share/man/man5/sshd_config.5.gz
Notice that the word can appear anywhere in the path, not only at the end. By default the pattern is treated as a plain substring: locate hosts matches /etc/hosts and also /usr/lib/ghostscript, because the letters hosts sit inside ghostscript. This is the number-one surprise for new users, and section 5 shows how to tighten it.
4.2 Search Case-Insensitively
By default the match is case-sensitive. The -i flag (short for ignore case) makes it match regardless of capitals, which is what you want when you are not sure how a file was named:
$ locate -i readme
/opt/app/README.md
/usr/share/doc/bash/readme.txt
4.3 Count Instead of List
When you only want to know how many matches exist, the -c flag (short for count) prints a number instead of a long list:
$ locate -c .conf
1873
This is a fast way to gauge the size of a result before you flood your screen with it.
4.4 Search for Several Words at Once
You can pass more than one pattern. Here is the one behavior where plocate and the older mlocate genuinely differ, so it is worth knowing which you have. On plocate, giving several patterns means "match all of them", like an AND:
$ locate nginx conf # plocate: paths containing BOTH "nginx" and "conf"
/etc/nginx/nginx.conf
/etc/nginx/conf.d/default.conf
On mlocate, the same command means "match any of them" (an OR), and you would add -A (short for all) to require all of them. plocate accepts -A too but ignores it, because AND is already its default.
5. Moderate Use Cases
5.1 Match Only the File Name, Not the Folders
Because the default match looks at the whole path, a search can pick up matches hidden in directory names higher up. The -b flag (short for basename) restricts the match to the last part of the path, the file name itself:
$ locate -b conf # too broad: "conf" appears in many folder names
$ locate -b '\.conf' # still substring, but only against file names
The directories are still printed in the result; they are just no longer allowed to trigger the match. This is the cleanest way to cut down noise when a common word appears in many parent folders.
5.2 Use Wildcards for Precise Matches
The moment your pattern contains a shell wildcard (*, ?, or [ ]), locate stops treating it as a substring and treats the whole thing as a glob pattern. This is the trick to anchor a search. Compare:
$ locate passwd # substring: matches anywhere, e.g. /etc/pam.d/passwd
$ locate '*/passwd' # glob: path must END in /passwd
/etc/passwd
/usr/bin/passwd
Always quote a pattern that contains a wildcard, so the shell hands it to locate untouched instead of expanding it against the current folder. A useful rule follows from how glob matching works: to match a plain substring with a glob you must wrap it in stars, '*name*', because a bare glob is anchored to the ends of the path.
5.3 Show Only Files That Still Exist
Because the database can be up to a day old, it may list files that were deleted since the last update. The -e flag (short for existing) checks each result against the live disk and drops the ones that are gone:
$ locate -e report.pdf # only paths that are actually on disk right now
/home/peter/report.pdf
This costs a little speed, because now locate does touch the filesystem to verify each hit, but it removes the "file not found" surprise when you act on the results.
5.4 Stop After a Few Matches
On a big system a pattern can match thousands of paths. The -l flag (short for limit) stops after a set number, which is perfect when you only need to confirm that something exists or to peek at the first few:
$ locate -l 5 .service # first 5 matches, then stop
/etc/systemd/system/multi-user.target.wants/cron.service
/lib/systemd/system/cron.service
...
5.5 Feed Results Safely to Another Command
Filenames on Linux may contain spaces and even newlines, which break a naive pipe. The -0 flag (short for the null separator) ends each result with an invisible null byte instead of a newline, and xargs -0 reads that same separator:
$ locate -0 '*.bak' | xargs -0 ls -lh
No filename can contain a null byte, so this handles every odd name without a surprise. Make it your default whenever locate feeds another command through a pipe.
6. Advanced Use Cases
6.1 Where the Database Comes From: updatedb
Everything locate knows comes from one file, the database, and one command builds it: updatedb. It runs as root so it can see the whole disk, walks the filesystem, and writes the index that locate later reads. On a modern system it runs automatically once a day through a systemd timer or a cron job:
$ systemctl list-timers | grep updatedb
plocate-updatedb.timer plocate-updatedb.service
If you just created files and want to search for them now, you do not have to wait for tomorrow's run. Trigger it yourself:
$ sudo updatedb # rebuild the index now, then locate sees new files
6.2 Controlling What Gets Indexed
You rarely want every path in the index. Temporary files, network mounts, and virtual filesystems would only bloat it and slow the daily run. The file /etc/updatedb.conf tells updatedb what to skip:
PRUNEPATHS="/tmp /var/spool /media"
PRUNEFS="nfs cifs tmpfs proc sysfs devtmpfs"
PRUNENAMES=".git .svn .hg"
PRUNEPATHSlists directories to skip entirely.PRUNEFSlists filesystem types to skip, so a mounted network share or a virtual/procis never crawled.PRUNENAMESlists directory names to skip wherever they appear, such as.gitfolders.
This is why locate usually will not find a file under /tmp: that path is pruned on purpose. If a whole area of your disk seems invisible to locate, this file is the first place to look.
6.3 Searching a Different Database
You are not limited to the system index. The -d flag (short for database) points locate at another index file, which is handy for a custom index of a large project or an external drive:
$ updatedb -l 0 -o photos.db -U /mnt/photos # build a private index
$ locate -d photos.db beach # search only that index
The -l 0 above turns off the permission-visibility feature for a private index you build yourself, and -U tells updatedb which directory to index. You can also set the LOCATE_PATH environment variable to add an extra database to every search automatically.
6.4 Real Regular Expressions
When globs are not expressive enough, locate can match with regular expressions. The -r flag (short for regexp) uses POSIX basic regex, and --regex uses the extended flavour, the same as grep -E:
$ locate --regex '/(nginx|apache2)/.*\.conf$'
/etc/nginx/nginx.conf
/etc/apache2/apache2.conf
There is a cost worth understanding. Normally plocate jumps straight to candidates using its index and barely touches the database. A regex cannot use that index, so it forces a slow linear scan of every entry. Use regex when you need it, but prefer a glob when a glob will do.
6.5 Why locate Does Not Leak Private Files
The index is built by root and lists files that ordinary users cannot read. So how does locate avoid showing you your neighbour's private paths? It runs with the setgid bit, which lets it open the protected index, but before printing any result it checks whether you have permission to reach that path. If you lack read and execute permission on the parent directories, the match is silently dropped. The catalog is complete, but everyone sees only their own section of it.
7. Something Most Users Do Not Know
7.1 How plocate Is So Fast: the Trigram Index
The old locate was fast because it searched a small file instead of the disk, but it still read that entire file every time. plocate almost never does. Its secret is a trigram index. When the database is built, every path is chopped into overlapping three-letter pieces: /etc/hosts yields /et, etc, tc/, c/h, /ho, and so on. For each little trigram, the index stores a list of which paths contain it, a posting list, which is where the "p" in plocate comes from.
When you search for hosts, plocate breaks your word into the same trigrams, looks up the short posting lists, and intersects them to get a tiny set of candidate paths. Only those few candidates are checked in full. It never scans the whole database, so the search stays fast even as the index grows to hundreds of megabytes. The one exception is a pattern shorter than three letters, which has no full trigram to look up and forces a scan; that is why very short searches feel slower.
The difference is easy to feel for yourself. Time a locate lookup against the equivalent find walk of the whole disk:
$ time locate kernel
...
real 0m0.02s
$ time find / -name "*kernel*" 2>/dev/null
...
real 0m21.7s
Both return the same files, but locate reads a ready-made index while find opens every directory on the system. On a large server that is the difference between an instant answer and a coffee break.
7.2 Knowing Where locate Stops
Part of expertise is knowing which tool takes over when locate reaches its edge:
| Need | Use | Why |
|---|---|---|
| Find a file created seconds ago | find |
locate only knows what the last daily updatedb recorded |
| Search by size, age, owner, or permission | find |
The index stores names only, not metadata |
| Search inside file contents | grep |
locate matches path names, never what is written in a file |
| Find the program behind a command | which / type |
They resolve a name against $PATH, which is exactly what you want there |
The healthy habit is to reach for locate first for any "where does that file live?" question, because it answers instantly, and fall back to find only when you need freshness or a test on size, age, or permissions.
8. Best Practices
- Reach for
locatefirst,findsecond. For a plain "where is this file" question it is far faster; usefindwhen you need live results or metadata tests. - Run
sudo updatedbafter big changes. If you just installed software or created files andlocatecannot see them, the index is simply stale. Refresh it. - Quote patterns with wildcards. Write
locate '*/passwd', notlocate */passwd, or the shell expands the pattern beforelocatesees it. - Use
-bto cut noise. When a common word hides in many folder names, match only the basename. - Add
-ewhen you will act on the results. It drops paths that no longer exist, so you do not chase a deleted file. - Prefer a glob over a regex. A glob uses the fast index;
-rand--regexforce a full scan. - Use
-0 | xargs -0in pipes. It is the only safe way to pass results with spaces or newlines to another command.
When you need the full detail, the documentation is one command away:
$ man locate # the manual for your locate (often plocate or mlocate)
$ locate --help # a quick summary of every option
$ man updatedb # how the index is built and scheduled
Back to top9. Common Mistakes
9.1 Four Common Myths
| Myth | Reality |
|---|---|
"locate searches my disk." |
It reads a database built once a day by updatedb, never the live disk. |
"If locate cannot find it, the file is gone." |
It may just be newer than the last index, or in a pruned path like /tmp. Run updatedb. |
"locate name matches only files called name." |
It matches name as a substring anywhere in the path. Use a glob or -b to narrow it. |
"locate and find do the same thing." |
Same goal, opposite methods: locate is a fast stale index, find is a live but slower walk. |
9.2 Other Traps to Avoid
- Expecting brand-new files. A file created after the last
updatedbwill not appear until the index refreshes. This is the single most common confusion. - Forgetting pruned paths.
/tmp, network mounts, and virtual filesystems are excluded on purpose in/etc/updatedb.conf, solocatewill never list them. - Unquoted wildcards. An unquoted
*is expanded by the shell first, solocateends up searching for the wrong thing. - Reaching for regex too soon.
-rand--regexdisable the fast index and scan everything. A glob is usually enough and far quicker. - Assuming plocate and mlocate agree on multiple patterns. Several patterns mean AND on
plocatebut OR onmlocate. Check which you have before you trust the result. - Running
locateas the only check before deleting. The list may be stale. Confirm with-e, or withls, before you act.
10. Summary
The locate command finds files by name across the whole system almost instantly, by looking them up in a prepared index instead of searching the disk.
locatereads a database built once a day byupdatedb; it is fast because it never walks the live filesystem.- The trade-off is freshness: brand-new files are missing until the index updates, so run
sudo updatedbwhen you need current results. - The name you type is usually
plocateormlocate; the prefix records the tool's history from secure to merging to posting-list. - Patterns match as a substring by default; a wildcard turns the pattern into an anchored glob, and
-blimits the match to the file name. - Everyday flags:
-i(ignore case),-c(count),-e(only existing),-l(limit),-0(safe piping). - Control what is indexed through
/etc/updatedb.conf, and usefindwhen you need freshness, metadata, or content search.
This is the quick reference worth keeping:
locate hosts paths containing "hosts" anywhere
locate -i readme same, ignoring upper/lower case
locate -c .conf count the matches instead of listing them
locate nginx conf plocate: paths matching BOTH words
locate -b '\.conf' match the file name only, not the folders
locate '*/passwd' glob: path must end in /passwd
locate -e report.pdf only results that still exist on disk
locate -l 5 .service stop after the first 5 matches
locate -0 '*.bak' | xargs -0 ls -lh safe pipe for odd names
locate --regex '\.log$' match with an extended regular expression
sudo updatedb rebuild the index now
man updatedb how the index is built and pruned
Once locate is part of your habits, a large server stops feeling like a maze. You stop guessing where things live and simply ask, and the answer arrives before you have finished the thought. If your servers have grown into something no one can quite navigate anymore, sorting that out, and keeping it fast and tidy, is exactly the kind of work I help with.


Peter is a Joomla specialist and a Linux admin for fast, secure and scalable websites.


