Self-hosted code search in 2026: revisit Zoekt, OpenGrok and Hound before you clone another fifty repos to find one function
Every growing engineering team reaches the same moment. Someone asks “where else do we call this function?”, and the honest answer is to clone fifty repositories and run grep across them. That works once. It does not work every week, and it does not work for the new joiner who does not even know which fifty repositories exist. This post revisits three self-hosted code search tools, Zoekt, OpenGrok and Hound, and looks at what each one is good at and what it costs to run.
This is not a ranking. The notes below come from the projects’ own repositories, documentation and licence files. No hands-on benchmark was run for this post, so no speed numbers are quoted.
Why revisit code search now
- Code is spread across more repositories than before: services, infrastructure code, shared libraries, forks of open-source projects. Local grep only sees what you have cloned.
- Security work depends on search. When a vulnerable library or a leaked key pattern is reported, the first question is “where do we use this?”, and the answer is needed in minutes.
- Hosted code search is tied to one code host. Teams that run GitLab, Gitea and a few GitHub organisations together need something that sits above all of them.
- The licence picture changed. Sourcegraph, which many teams used as their self-hosted code search, no longer develops its main product in a public open-source repository; github.com/sourcegraph/sourcegraph is no longer publicly visible. Its free tier and paid plans still exist, but teams that wanted a fully open-source option have started looking again at the older, simpler engines.
The common idea: trigram indexes
All three tools avoid scanning every file for every query. Zoekt and Hound both build on the approach Russ Cox described in his article “Regular Expression Matching with a Trigram Index”, written after his work on Google Code Search. The idea is simple:
- Break every file into overlapping three-character pieces (trigrams) and record where each one appears.
- When a query arrives, work out which trigrams any match must contain, look them up, and only read the candidate files.
- Run the real regular expression only on those candidates.
OpenGrok takes a different route. It uses Apache Lucene, the Java full-text search library, plus Universal Ctags for symbol definitions. That makes it closer to a search engine with cross-reference features than a pure regex tool.
Zoekt: fast substring and regex search at scale
Zoekt was created by Han-Wen Nienhuys and first published as github.com/google/zoekt. Since 2017 the maintained source has been the fork at github.com/sourcegraph/zoekt, and its README says so directly. Sourcegraph still uses Zoekt as the search backend inside its own product, so the engine gets steady attention even though the wider Sourcegraph product is no longer developed in a public open-source repository.
What it does well:
- Fast substring and regular expression matching with a rich query language: boolean and, or and not, filters on repository, file name, language and more.
- Ranking that uses code signals, for example giving more weight to matches on symbol names, using syntactic parsing through ctags.
- Two ways to run it. You can use the command line tools to index and search, or run the indexserver and webserver, which sync repositories from a code host and serve a web UI and an API.
- It is built for many repositories, so it suits organisations with hundreds or thousands of repos.
What to check before you commit:
- Licence. Zoekt is Apache-2.0, which is permissive and comfortable for company use, including internal modifications.
- The web UI is basic. Zoekt is an engine first. If people expect code navigation, “go to definition” and blame views, you will need to build around it or accept a plain results page.
- Index shards take disk space and memory. Plan storage for the index next to the mirrored repositories, and size the host after indexing a realistic sample, not after a guess.
- Documentation lives in the doc directory of the repository. Read the design notes before tuning; the defaults assume the indexserver is in charge of fetching code.
OpenGrok: cross-reference and history for large source trees
OpenGrok was originally conceived at Sun Microsystems by Chandan B.N., and it moved to Oracle with Sun. It is written in Java and is still actively released; the latest release at the time of writing is 1.14.20, published in October 2026 on GitHub.
What it does well:
- Cross-referencing. OpenGrok shows definitions, references and file history, so it works like a browsable source tree, not only a search box. This is why it has long been popular for operating system and large C and C++ code bases.
- It understands many version control systems, not only Git, which helps teams that still carry Mercurial, Subversion or other older history.
- Full-text search, definition search, symbol search, path search and history search are separate fields, which is easy to explain to non-specialists.
- Universal Ctags provides symbol data for a long list of languages.
What to check before you commit:
- Licence. The project is under the Common Development and Distribution License (CDDL) version 1.0, with exceptions noted in individual files. CDDL is a weak copyleft licence at file level. Internal use is simple; if you modify OpenGrok files and distribute them, those files must stay under CDDL. Ask your legal team once and record the answer.
- Operations are heavier. You run a Java web application in a servlet container such as Tomcat, plus the indexer, plus Universal Ctags at a supported version. There are official Docker images, which reduce the setup work.
- Indexing large trees with history takes time. Schedule reindexing, and watch for history indexing being the slowest part.
- It is oriented to a source root on disk. You are responsible for cloning and pulling repositories into that root, usually with the provided sync tools or your own scripts.
Hound: small, simple and easy to run
Hound was created at Etsy, as its README credits, and now lives at github.com/hound-search/hound. Its README describes it as a static React frontend talking to a Go backend, with the core based on Russ Cox’s trigram article and code. The backend keeps an index for each repository and answers searches through a minimal API.
What it does well:
- Very simple setup. One JSON config file lists the repositories, Hound clones and polls them, and you get a search page.
- Regex search across repositories with file path filters, which covers most “where do we use this?” questions.
- Low operational surface: one Go binary and its data directory. It fits on a small VM or a single container.
- Licence. Hound is MIT, the simplest of the three.
What to check before you commit:
- Release pace is slow. The latest tagged release on GitHub is v0.7.1 from May 2023, although the repository still gets commits, the latest in September 2026. Decide whether you are comfortable building from source.
- It is a search page, not a code navigation tool. No cross-reference and no symbol-aware ranking.
- Configuration is a static file. For hundreds of repositories you will want a small script that generates the config from your code host’s API.
- There is no built-in user login. Put it behind your reverse proxy with single sign-on, as you would any internal tool that exposes source code.
Security and access: the part teams skip
A code search server holds a copy of every repository it indexes. Treat it like a code host, not like a wiki.
- Use a read-only, dedicated token or deploy key for mirroring. Do not reuse a person’s token.
- Put the UI behind single sign-on. None of these tools should be exposed to the internet directly.
- Be careful with repository permissions. If some repositories are restricted, the simplest safe option is a separate instance for them, because these engines do not mirror your code host’s per-repository permissions out of the box.
- Remember that search makes secrets easier to find. That is useful for your security team and also for an attacker. Run a secret scanner in CI and rotate anything that search turns up.
- Back up the configuration, not the index. Indexes can be rebuilt from the mirrors; the list of repositories and the tokens setup are what you will miss.
When to pick which
- Pick Zoekt when you have many repositories, want fast regex search with sensible ranking, and want a permissive Apache-2.0 licence. Accept a plain UI or plan to build a small one.
- Pick OpenGrok when people need to browse code, follow definitions and references, and read history, especially in large C, C++ or Java trees or mixed version control systems. Accept a Java stack and longer indexing.
- Pick Hound when you want something running this afternoon for tens of repositories, with the least moving parts and an MIT licence. Accept slow releases and no navigation features.
- Stay with your code host’s built-in search, or a paid product, when you need per-repository permissions mirrored automatically and you do not have time to run another service.
An example team (invented)
The following team is invented to show the reasoning. A twelve-person platform team in Pune looks after around 180 repositories spread over a self-hosted GitLab and two GitHub organisations. Every library upgrade starts with someone cloning a pile of repositories and running grep, and new joiners keep asking which service owns which config key.
- They first try Hound on a small VM with a generated config of all 180 repositories. It works, and people like it, but the ranking is weak when a common function name matches hundreds of files.
- They then pilot Zoekt with the indexserver mirroring both GitLab and GitHub using read-only tokens. Symbol-aware ranking helps, and the query filters by repository and language cut the noise.
- One older C code base with long Subversion history goes into a separate OpenGrok instance, because the engineers working on it mainly need cross-reference and history, not cross-repository regex.
- Both instances sit behind the company single sign-on, and the restricted payments repositories are left out of the shared index on purpose.
The point is not the final mix. The point is that they matched each tool to a real question their engineers asked, and they tested with their own repositories before deciding.
A practical checklist
- List the questions people actually ask: “where is this called”, “who uses this config key”, “which repos still pull this library version”.
- Count repositories, total size and code hosts. This decides whether a simple tool is enough.
- Read the licence file of the tool you choose, and record the decision: Apache-2.0 for Zoekt, CDDL 1.0 for OpenGrok, MIT for Hound.
- Create a dedicated read-only token or deploy key for mirroring.
- Decide how restricted repositories are handled before the first index, not after.
- Put the UI behind single sign-on and keep it off the public internet.
- Index a realistic sample, measure disk and memory yourself, then size the host.
- Schedule reindexing and alert when it fails, so search results do not quietly go stale.
- Add a secret scanner in CI, because better search will surface old secrets.
- Review in six months: is the tool used, are results fresh, and is the project still maintained?
Closing thought
Code search is one of those tools that seems optional until you have it. You do not need the biggest platform to get most of the value. A trigram index, a list of repositories and a login in front of it will save your team many afternoons of cloning and grepping. Start small, test on your own code, and pick the tool whose trade-offs you are willing to live with.
Releted Posts
Self-hosted notes in 2026: revisit Joplin, Trilium Notes and Memos before you paste another runbook into a hosted notes app
Notes are where engineers keep the small things that matter: the command that fixed last month’s outage, the half-written design idea, the client’s odd network rule.
Read moreSelf-hosted invoicing in 2026: revisit Invoice Ninja, Akaunting and SolidInvoice before you send another invoice from a spreadsheet
Most small teams start invoicing the same way. Someone copies last month’s invoice in a spreadsheet, changes the number and the date, exports a PDF and emails it.
Read moreSelf-hosted scheduling and booking in 2026: revisit Cal.com, Easy!Appointments and Rallly before you share another Calendly link
Booking a meeting looks like a small thing. You share a link, the other person picks a slot, and an invite lands in both calendars.
Read more