Skip to main content

Linux command: locate

15 July 2026

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.

The right mental model: locate is a card catalog, and find is 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.

Back to top

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:

NamePrefix stands forWhat 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.

Back to top

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:

EraMilestone
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.

Back to top

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.

Back to top

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.

Back to top

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"
  • PRUNEPATHS lists directories to skip entirely.
  • PRUNEFS lists filesystem types to skip, so a mounted network share or a virtual /proc is never crawled.
  • PRUNENAMES lists directory names to skip wherever they appear, such as .git folders.

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.

Back to top

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:

NeedUseWhy
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.

Back to top

8. Best Practices

  • Reach for locate first, find second. For a plain "where is this file" question it is far faster; use find when you need live results or metadata tests.
  • Run sudo updatedb after big changes. If you just installed software or created files and locate cannot see them, the index is simply stale. Refresh it.
  • Quote patterns with wildcards. Write locate '*/passwd', not locate */passwd, or the shell expands the pattern before locate sees it.
  • Use -b to cut noise. When a common word hides in many folder names, match only the basename.
  • Add -e when 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; -r and --regex force a full scan.
  • Use -0 | xargs -0 in 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 top

9. Common Mistakes

9.1 Four Common Myths

MythReality
"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 updatedb will 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, so locate will never list them.
  • Unquoted wildcards. An unquoted * is expanded by the shell first, so locate ends up searching for the wrong thing.
  • Reaching for regex too soon. -r and --regex disable 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 plocate but OR on mlocate. Check which you have before you trust the result.
  • Running locate as the only check before deleting. The list may be stale. Confirm with -e, or with ls, before you act.
Back to top

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.

  • locate reads a database built once a day by updatedb; 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 updatedb when you need current results.
  • The name you type is usually plocate or mlocate; 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 -b limits 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 use find when 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.

Back to top
Linux command: locate
Peter Martin
Peter Martin
Joomla Specialist

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