plocate: The Locate Rewrite That Replaces a Full Filesystem Scan With a Trigram Index

2026-08-30

Every Linux distro ships some flavor of locate — usually mlocate, which walks its ~200 MB database linearly for every query. On a laptop with a few million files, "find that config I edited last Tuesday" takes 2–5 seconds. Steinar Gunderson looked at that in 2020 and asked: why are we running grep across an entire index when search engines solved this in the 1970s? The result is plocate, and it is on the order of 10–1000× faster than mlocate on the same database.

The trick: plocate builds a posting-list index keyed by trigrams (every three-character substring of every filename). To answer plocate foo, it intersects the posting lists for foo and returns only the matching filenames — no scan required. The database is also smaller than mlocate's, and it's zstd-compressed by default.

Install and index:

# Debian/Ubuntu ships it; Fedora and Arch too
sudo apt install plocate
sudo updatedb  # takes ~2 min for /, then you never think about it again

ls -lh /var/lib/plocate/plocate.db
# -rw-r----- 1 root plocate 63M  # vs 180M+ for mlocate on the same tree

Interactive queries — the "why isn't everything this fast" moment:

# mlocate: 2.3 seconds
# plocate: 0.008 seconds
plocate nginx.conf

# Regex works and stays fast because trigrams pre-filter
plocate --regex '\.env\.(prod|staging)$'

# Only files that still exist (io_uring parallel stat)
plocate --existing containerd.sock

The killer feature nobody advertises--basename combined with case-insensitive glob:

# Find every Dockerfile anywhere, case-insensitive, in ~5ms
plocate -i -b '\bDockerfile\b'

# Pipe to fzf for a live filesystem picker
plocate '' | fzf --preview 'bat --color=always {}'

Keep the index fresh without a cron job. The Debian package installs a systemd timer at plocate-updatedb.timer — check it with systemctl list-timers plocate*. If you're building a container or a fresh VM and want an index right now:

# Only index specific trees — a fraction of the time and space
sudo updatedb --output=/tmp/code.db \
  --database-root=/home/shaun/src \
  --prune-bind-mounts=yes

Then query that private DB explicitly:

plocate -d /tmp/code.db 'CMakeLists.txt'

Where it beats the alternatives:

Two footguns. First: plocate respects file permissions via the plocate group — a search will hide directories your user can't x into. That's a feature, but if you expected to see something and don't, check getfacl on its parents. Second: queries shorter than three characters degrade to a full scan (there's no trigram to index). Anything ≥ 3 characters stays in the fast path.

Key Takeaway: plocate turns filesystem search into a posting-list intersection instead of a linear scan, giving you sub-10ms queries against millions of files with a drop-in mlocate-compatible CLI.

All newsletters