v0.20.1 makes text search cover the full content of every text file. Before, Seek skipped files above 100 MiB, and Zoekt skipped text files with more than 20,000 distinct trigrams, so a search could miss a file that rg found. This release also builds the 13 Go vulnerability fixes published on 2026-10-08 into the binary, and fixes cancelled searches that printed partial results.
Changes
-
Text search covers the full content of every text file, of any size and with any number of distinct trigrams. The only limit for one file is the Zoekt format: one index shard holds at most 4 GiB. A file whose shard would be larger keeps only its name in the text index. Zoekt also keeps only the name of a file with a NUL byte and of a file shorter than three bytes, because it has no option to index them. Seek reads the first 8,000 bytes of a file first and stops there when they hold a NUL byte, so binary folders index as fast as before.
-
When a search of an exact file finds no content match and the index holds that file by name only, Seek writes the reason to standard error:
File content is not searchable file=... reason="NOT-INDEXED: contains binary content"The reason comes from the index, so Seek does not keep a copy of Zoekt's rules. Searches of folders and repositories do not write this warning.
-
Large-file builds use more of the host. The read budget is a quarter of physical memory, at least 2,400 MiB, in place of a fixed 2,400 MiB. Files that fill a shard alone build one per CPU, at least 3, in place of 3 at a time. A cold index of 8 files of 200 MiB fell from 11.6–12.3 s to 6.3–7.3 s, and its peak memory rose from 6.5–7.8 GB to 9.8–10.7 GB.
-
A cancelled search, for example after Ctrl-C, stops with the cancellation error and exit code 2. Before, it could print the partial results of the shards it had searched, or the BM25 order in place of the model order, as if the search was complete.
-
Seek no longer closes the model while a query encoding is in progress. This could occur on the combined route when index preparation stopped early, for an empty corpus or a setup error.
-
A search that cannot read vectors does not build them. This applies to the lexical route and to a dirty Git tree. A dirty-tree search still re-ranks its lexical candidates, and the next clean search builds the vectors. An embedding fault now runs the build one time, not three. Before, the three faults could make the provider reject itself.
-
In combined search, a file that both branches found keeps its lexical rank when the candidate pool fills before the merge reaches its lexical entry. Before, later steps saw no lexical support for that file.
-
Search output now ends with one newline. Before, the last line had no line terminator, so a shell prompt started on the line of the last match.
-
A model start creates one tokenizer, not one per CPU. Only an index build fills the pool, in parallel. On an 18-CPU host, this removes about 0.4 to 0.5 s of CPU time from each search that uses the model.
-
Seek reads each directory one time to correct the case of path operands. With 1,000 file operands in one Git directory, a warm search fell from 0.67–0.70 s to 0.19–0.21 s.
Security
v0.20.0 was built with Go 1.27.0 and golang.org/x/net v0.58.0. govulncheck reports 13 vulnerabilities in these versions, published on 2026-10-08, and reports six of them as called: GO-2026-6603, GO-2026-6608, GO-2026-6611, GO-2026-6612, GO-2026-6613, and GO-2026-6617. The call paths go through calls that static analysis cannot resolve, and Seek starts no HTTP server, so the real exposure is probably low. v0.20.1 is built with Go 1.27.2 and golang.org/x/net v0.61.0, and govulncheck finds no vulnerabilities.
Dependencies
- Zoekt moves 22 commits, from
df97bab6to0e68f413. The shard format does not change. Shards load faster (sourcegraph/zoekt#1172), symbol regular expressions with alternation plan correctly (#1151), and new shards again put generated, vendored, and test files later in document order (#1164). - gRPC v1.84.0,
klauspost/compressv1.20.3,wasilibs/go-re2v1.13.0 (without wazero), Prometheus, and the othergolang.org/xmodules move to their latest releases.gobwas/globstays at v0.2.3, because v1.0.0 removes an interface that Zoekt uses.
Upgrade
The new content limit enters the cache key of every corpus. The first search of each repository, file, or folder therefore rebuilds its text index and, for an eligible description, its meaning-based data. On a large repository this can take tens of seconds and several GiB of memory; --lexical-only skips the meaning-based half. seek gc removes the old corpora after the unused age, 14 days by default.
The rebuild indexes more content than before. On a monorepo, the cold index time did not change (1.70–1.81 s against 1.69–1.82 s), and a warm search took 3% longer for 22% more indexed content. Files with much non-ASCII text, such as CJK prose, need much memory to index: 100 MiB of random CJK characters needed 6.6 GiB.
Because every index is rebuilt, Zoekt's new document order applies at once, and the order of some results can change.
Scripts that read Seek's output must accept a final newline.
Source builds still need Go 1.27 or newer, CGO, and a native C compiler; use make build. go.mod now selects Go 1.27.2 with a toolchain line, so an older Go 1.27 downloads it when GOTOOLCHAIN permits.
Packages
Four archives support macOS 15 or newer and glibc Linux on amd64 and arm64. Linux packages were built on Ubuntu 24.04; musl is not supported. The release also includes SHA-256 checksums, a CycloneDX SBOM, build-provenance attestations, and SBOM attestations. Each archive contains the binary, license, and third-party notices. The binary contains its model and native libraries and uses no remote API. Seek needs Universal Ctags to build or update an index and Git 2.36 or later for Git-backed searches.
Install
curl -sSfL \
https://raw.githubusercontent.com/dualeai/seek/v0.20.1/install.sh |
sh -s -- v0.20.1Full changelog: v0.20.0...v0.20.1