next-plaid
Library Listed
CPU-based PLAID implementation for multi-vector search using ndarray
- Downloads
- 256
- Dependents
- 1
- Stars
- 610
- Forks
- 67
- Contributors
- 21
- Commits
- 765
- Latest release
- 1.8.5 ·
About
NextPlaid & ColGREP
NextPlaid is a multi-vector search engine. ColGREP is semantic code search, built on it.

ColGREP
Semantic code search for your terminal and your coding agents. Searches combine regex filtering with semantic ranking. All local, your code never leaves your machine.
Quick start
Install with Homebrew (macOS / Linux):
brew install lightonai/tap/colgrep && colgrep --install-agent
or with the shell installer:
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/lightonai/next-plaid/releases/latest/download/colgrep-installer.sh | sh && "${CARGO_HOME:-$HOME/.cargo}/bin/colgrep" --install-agent
colgrep --install-agent downloads the local model behind agent mode (one-time, 2.5 GB): a small model that explores your codebase like a sub-agent and returns the code locations that answer a question. To install colgrep alone, drop the && … part; you can run colgrep --install-agent later.
Build the index:
colgrep init /path/to/project # specific project
colgrep init # current directory
Search:
colgrep "database connection pooling"
Read the full README
Or ask the agent: it searches with colgrep, reads the candidates, and returns the exact lines that answer the question (after colgrep --install-agent):
colgrep --agent "where is the database connection pool configured"
That's it. No server, no API, no dependencies. ColGREP is a single Rust binary with everything baked in. colgrep init builds the index for the first time. After that, every search detects file changes and updates the index automatically before returning results.
Regex meets semantics:
colgrep -e "async.*await" "error handling"
Change the model
The default is lightonai/LateOn-Code-edge. Switch to any other ColBERT-style model on HuggingFace:
# Persist as the default (existing indexes for other models are kept)
colgrep set-model lightonai/LateOn-Code
# One-shot override for a single query or init
colgrep --model lightonai/LateOn-Code "database connection pooling"
# See which model an index was built with
colgrep status
# Private HuggingFace model
HF_TOKEN=hf_xxx colgrep set-model myorg/private-model
Each (project, model) pair has its own index directory, so switching models never corrupts existing indexes and you can flip back and forth without re-indexing. colgrep clear scopes to the active model; colgrep clear --all wipes every index.
Agent integrations
| Tool | Install |
|---|---|
| Claude Code | colgrep --install-claude-code |
| OpenCode | colgrep --install-opencode |
| Codex | colgrep --install-codex |
| Hermes | colgrep --install-hermes |
Restart your agent after installing. Claude Code has full hooks support. OpenCode, Codex, and Hermes integrations are basic for now, PRs welcome.
How it works
flowchart TD
A["Your codebase"] --> B["Tree-sitter"]
B --> C["Structured representation"]
C --> D["LateOn-Code-edge · 17M"]
D --> E["NextPlaid"]
E --> F["Search"]
B -.- B1["Parse functions, methods, classes"]
C -.- C1["Signature, params, calls, docstring, code"]
D -.- D1["Multi-vector embedding per code unit · runs on CPU"]
E -.- E1["Rust index binary · quantized · memory-mapped · incremental"]
F -.- F1["grep-compatible flags · SQLite filtering · semantic ranking
100% local, your code never leaves your machine"]
style A fill:#4a90d9,stroke:#357abd,color:#fff
style B fill:#50b86c,stroke:#3d9956,color:#fff
style C fill:#50b86c,stroke:#3d9956,color:#fff
style D fill:#e8913a,stroke:#d07a2e,color:#fff
style E fill:#e8913a,stroke:#d07a2e,color:#fff
style F fill:#9b59b6,stroke:#8445a0,color:#fff
style B1 fill:none,stroke:#888,stroke-dasharray:5 5,color:#888
style C1 fill:none,stroke:#888,stroke-dasharray:5 5,color:#888
style D1 fill:none,stroke:#888,stroke-dasharray:5 5,color:#888
style E1 fill:none,stroke:#888,stroke-dasharray:5 5,color:#888
style F1 fill:none,stroke:#888,stroke-dasharray:5 5,color:#888
Agent mode. Your coding agent (Claude, GPT, Gemini, …) can call colgrep itself, or hand the whole question to colgrep --agent: a small search model that runs on your machine, calls colgrep as many times as it needs, reads the candidates, and returns only the lines that answer. The large model gets the answer without spending its context on the search.
flowchart TD
L["Coding agent · Claude, GPT, Gemini, …"]
A["colgrep --agent · 2B search model"]
S["colgrep"]
M["LateOn-Code-edge · 17M"]
I["NextPlaid index"]
L -->|"delegates a question"| A
L -->|"or searches directly"| S
A -->|"many searches and reads"| S
S --> M
M --> I
A -. "file:line locations" .-> L
L -.- L1["Plans, edits, reviews · large model, any provider"]
A -.- A1["Searches, reads files read-only, picks the exact lines
runs locally on GPU or CPU"]
M -.- M1["Multi-vector embedding per code unit · runs on CPU"]
style L fill:#4a90d9,stroke:#357abd,color:#fff
style A fill:#9b59b6,stroke:#8445a0,color:#fff
style S fill:#50b86c,stroke:#3d9956,color:#fff
style M fill:#e8913a,stroke:#d07a2e,color:#fff
style I fill:#e8913a,stroke:#d07a2e,color:#fff
style L1 fill:none,stroke:#888,stroke-dasharray:5 5,color:#888
style A1 fill:none,stroke:#888,stroke-dasharray:5 5,color:#888
style M1 fill:none,stroke:#888,stroke-dasharray:5 5,color:#888
What the model sees. Each code unit is converted to structured text before embedding:
# Function: fetch_with_retry
# Signature: def fetch_with_retry(url: str, max_retries: int = 3) -> Response
# Description: Fetches data from a URL with retry logic.
# Parameters: url, max_retries
# Returns: Response
# Calls: range, client.get
# Variables: i, e
# Uses: client, RequestError
# File: src/utils/http_client.py
def fetch_with_retry(url: str, max_retries: int = 3) -> Response:
"""Fetches data from a URL with retry logic."""
for i in range(max_retries):
try:
return client.get(url)
except RequestError as e:
if i == max_retries - 1:
raise e
This structured input gives the model richer signal than raw code alone.
Documentation: install variants, performance tuning, all flags and options → ColGREP documentation
Benchmark
ColGREP against Semble public bench: 1,251 queries × 63 repos × 19 languages (FP32).
Why multi-vector?
Standard vector search collapses an entire document into one embedding. That's a lossy summary. Fine for short text, bad for code where a single function has a name, parameters, a docstring, control flow, and dependencies.
Multi-vector keeps ~300 embeddings of dimension 128 per document instead of one. At query time, each query token finds its best match across all document tokens (MaxSim). More storage upfront. That's what NextPlaid solves with quantization and memory-mapped indexing.
NextPlaid
A local-first multi-vector database with a REST API. It's what powers ColGREP under the hood, but it's a general-purpose engine you can use for any retrieval workload.
- Built-in encoding. Pass text, get results. Ships with ONNX Runtime for ColBERT models, no external inference server needed.
- Memory-mapped indices. Low RAM footprint, indices live on disk and are paged in on demand.
- Product quantization. 2-bit or 4-bit compression. A million documents fit in memory.
- Incremental updates. Add and delete documents without rebuilding the index.
- Metadata pre-filtering. SQL WHERE clauses on a built-in SQLite store. Filter before search so only matching documents are scored.
- CPU-optimized. Designed to run fast on CPU. CUDA supported when you need it.
NextPlaid vs FastPlaid. FastPlaid is a GPU batch indexer built for large-scale, single-pass workloads. NextPlaid wraps the same FastPlaid algorithm into a production API that handles documents as they arrive: incremental updates, concurrent reads/writes, deletions, and built-in encoding. Use FastPlaid for bulk offline indexing and experiments, NextPlaid for serving and streaming ingestion.
Quick start
Run the server (Docker):
# CPU
docker pull ghcr.io/lightonai/next-plaid:cpu-1.8.5
docker run -p 8080:8080 -v ~/.local/share/next-plaid:/data/indices \
ghcr.io/lightonai/next-plaid:cpu-1.8.5 \
--host 0.0.0.0 --port 8080 --index-dir /data/indices \
--model lightonai/answerai-colbert-small-v1-onnx --int8
# GPU
docker pull ghcr.io/lightonai/next-plaid:cuda-1.8.5
docker run --gpus all -p 8080:8080 -v ~/.local/share/next-plaid:/data/indices \
ghcr.io/lightonai/next-plaid:cuda-1.8.5 \
--host 0.0.0.0 --port 8080 --index-dir /data/indices \
--model lightonai/GTE-ModernColBERT-v1 --cuda
Query from Python:
pip install next-plaid-client
from next_plaid_client import NextPlaidClient, IndexConfig
client = NextPlaidClient("http://localhost:8080")
# Create index
client.create_index("docs", IndexConfig(nbits=4))
# Add documents, text is encoded server-side
client.add(
"docs",
documents=[
"next-plaid is a multi-vector database",
"colgrep is a code search tool based on NextPlaid",
],
metadata=[{"id": "doc_1"}, {"id": "doc_2"}],
)
# Search
results = client.search("docs", ["coding agent tool"])
# Search with metadata filtering
results = client.search(
"docs",
["vector-database"],
filter_condition="id = ?",
filter_parameters=["doc_1"],
)
# Delete by predicate
client.delete("docs", "id = ?", ["doc_1"])
Or via the CLI (pip install "next-plaid-client[cli]"):
next-plaid index create docs
next-plaid document add docs --text "hello world"
next-plaid search docs "hello"
Once the server is running: Swagger UI · OpenAPI spec
Documentation: REST API reference, Docker Compose, environment variables → NextPlaid documentation
API Benchmarks
End-to-end benchmarks against the NextPlaid API on BEIR datasets. Documents are uploaded as raw text in parallel batches of 64. Search queries are sent as raw text, one at a time, with 16 concurrent workers to simulate real user traffic. All throughput numbers (docs/s, QPS) include encoding time — the model runs inside the API, so every document and query is embedded on the fly within the API.
Setup: lightonai/GTE-ModernColBERT-v1 on NVIDIA H100 80GB, top_k=100, n_ivf_probe=8, n_full_scores=4096. CPU search uses INT8-quantized ONNX encoding on the same machine.
| Dataset | Documents | MAP | NDCG@10 | NDCG@100 | Recall@10 | Recall@100 | Indexing (docs/s) | GPU QPS | GPU P95 (ms) | CPU QPS | CPU P95 (ms) |
|---|---|---|---|---|---|---|---|---|---|---|---|
| arguana | 8,674 | 0.2457 | 0.3499 | 0.3995 | 0.7126 | 0.9337 | 77.1 | 13.6 | 170.1 | 17.4 | 454.7 |
| fiqa | 57,638 | 0.3871 | 0.4506 | 0.5129 | 0.5184 | 0.7459 | 41.3 | 18.2 | 170.6 | 17.6 | 259.1 |
| nfcorpus | 3,633 | 0.1870 | 0.3828 | 0.3427 | 0.1828 | 0.3228 | 86.7 | 6.6 | 262.1 | 16.9 | 219.4 |
| quora | 522,931 | 0.8170 | 0.8519 | 0.8644 | 0.9309 | 0.9730 | 105.5 | 20.9 | 126.2 | 17.7 | 235.1 |
| scidocs | 25,657 | 0.1352 | 0.1914 | 0.2732 | 0.2020 | 0.4418 | 46.9 | 17.5 | 139.3 | 16.5 | 281.7 |
| scifact | 5,183 | 0.7186 | 0.7593 | 0.7775 | 0.8829 | 0.9633 | 53.1 | 7.9 | 169.5 | 16.9 | 305.4 |
Models
Any HuggingFace ColBERT-style model can be exported to ONNX. By default, both FP32 and INT8 quantized versions are created. INT8 quantization reduces size (~4x smaller) and improves speed with minimal quality loss.
pip install pylate-onnx-export
# Export model (creates model.onnx and model_int8.onnx)
pylate-onnx-export lightonai/GTE-ModernColBERT-v1 -o ./my-models
# Export + push to HuggingFace Hub
pylate-onnx-export lightonai/GTE-ModernColBERT-v1 -o ./my-models --push-to-hub myorg/my-onnx-model
Ready-to-use models
These can be served with NextPlaid and used with ColGREP without export:
| Model | Use case |
|---|---|
lightonai/LateOn-Code-edge | Code search, lightweight |
lightonai/LateOn-Code | Code search, accurate |
lightonai/mxbai-edge-colbert-v0-32m-onnx | Text retrieval, lightweight |
lightonai/answerai-colbert-small-v1-onnx | Text retrieval, lightweight |
lightonai/GTE-ModernColBERT-v1 | Text retrieval, accurate |
Any PyLate-compatible ColBERT model from HuggingFace can be used when converted to ONNX.
License
Apache-2.0
Citation
@software{next-plaid,
title = {NextPlaid, ColGREP: Multi-vector search, from database to coding agents.},
url = {https://github.com/lightonai/next-plaid},
author = {Sourty, Rapha\"{e}l},
contributors = {Dinaburg, Artem and Oruc, Omer Faruk and Tripathi, Abhishek and Carron, Igor and Hsu, Chao-Chun (Joe) and Ellis, Jonathan and NickSdot and Weitekamp, Raymond and R\k{a}czka, Szymon and Motliuk, Mark and Chechenev, Ivan},
year = {2026},
}
@misc{LateOn-Code,
title = {LateOn-Code: a Family of State-Of-The-Art Late Interaction Code Retrieval Models},
author = {Chaffin, Antoine},
url = {https://huggingface.co/collections/lightonai/lateon-code},
year = {2026}
}
Compatibility
- Runs on
- CUDA
What shows it
- CUDA: next-plaid feature cuda (dependency cudarc), colgrep feature cuda, next-plaid-cli feature cuda, next-plaid-onnx feature cuda
- Native code
- Required
- Binds native code: tree-sitter, libsqlite3-sys, ort-sys, tree-sitter-language, zstd-sys and 4 more
- Python bindings
- Has Python bindings
- next-plaid-onnx needs Python only with feature python
- License
- Apache-2.0
Compare with similar projects
Order: strongest tier first, then most downloads, then name, with unmeasured values last. A library counts downloads over 30 days. An app counts binary downloads per release. An app with none counts its crate downloads over 30 days. ML Rust runs this catalogue, so its closest project always gets a row.
| Project | Downloads | Dependents | Stars | Latest release | Runs on (GPU) | Native code | License |
|---|---|---|---|---|---|---|---|
|
CPU-based PLAID implementation for multi-vector search using ndarray Python bindings |
256 downloads over 30 days | 1 | 610 | 1.8.5 | CUDA | Binds native code: tree-sitter, libsqlite3-sys, ort-sys, tree-sitter-language, zstd-sys and 4 more | Apache-2.0 |
|
lancedb Featured
LanceDB: A serverless, low-latency vector database for AI applications |
615,090 downloads over 30 days | 102 | 11,863 | 0.41.0 | GPU support unknown | No native code found | Apache-2.0 |
|
Qdrant - High-performance, massive-scale Vector Database and Vector Search Engine for the next generation of AI. Also available in the cloud https://cloud.qdrant.io/ |
34,017 binary downloads per release | Not applicable | 35,478 | Not measured | Not measured | Apache-2.0 | |
|
Postgres extension for vector search (DiskANN), complements pgvector for performance and scale. Postgres OSS licensed. |
33,328 binary downloads per release | Not applicable | 3,161 | Not measured | Not measured | PostgreSQL | |
|
faiss-rs Listed
High-level bindings for Faiss, the vector similarity search engine |
19,449 downloads over 30 days | 5 | 250 | 0.13.0 | GPU support unknown | Binds native code: faiss-sys, faiss_c. Build uses a native toolchain: cmake (feature static) | Apache-2.0 OR MIT |
|
splintr Listed
Tokenizer for Rust and Python: pure Rust by default, with 18 bundled vocabularies and four backends covering BPE, SentencePiece and WordPiece. Its output matches Hugging Face tokenizers id for id on 14 model families, including GPT-2, Qwen, Whisper, T5 and BERT. Python bindings |
8,204 downloads over 30 days | 7 | 63 | 0.22.2 | GPU support unknown | Binds native code: pcre2-sys (feature pcre2) | MIT |
|
Vantage Point Tree search algorithm for fast nearest neighbour search in multi-dimensional metric spaces. |
919 downloads over 30 days | 2 | 32 | 2.1.0 | GPU support unknown | No native code found | BSD-2-Clause |
Why ListedNo archive, New or Featured rule places it, so it is Listed.
What it lacks for Featured
- It has 1 active dependents and 1 new dependents in 365 days. Featured needs 11 active dependents or 9 new dependents in 365 days. The repository route reads 610 stars, 67 forks and 21 contributors. It needs 4,539 stars, 434 forks and 79 contributors together.
What else the check found
- The last activity is on 10 Oct 2026, 30 days ago. The rules expect an update within 700 days. Dormancy rule
Exact rules: Listed, Featured library. The check on applied thresholds version 9.
Every rule outcome, as the check records it
expected-interval: version 1.8.5 base 700: E = 700 daysdormancy: last activity 2026-10-10, 30 days ago, E = 700: activefeatured: not featured: active_users 1 < 11 and new_adopters 1 < 9 and repository route stars 610 (needs 4539), forks 67 (needs 434), contributors 21 (needs 79)listed: listed: no archive, new or featured rule applies
Crates5 crates
Measurements and sources
Each signal row shows the raw value, its source and the fetch date. The Sources list gathers every distinct source on this page. Movement needs more history.
Sources6 sources
- Description: the crates.io description
- crates.io database dump, fetched
- RustSec advisory database, fetched
- GitHub repository, fetched
- crates.io package, fetched
- GitHub contributors, fetched
Adoption1 active dependents, 1 new dependents in 365 days1 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Active dependents | 1 | crates.io database dump | Yes | |
| New dependents (365 days) | 1 | crates.io database dump | Yes | |
| Peak active dependents | 1 | crates.io database dump | Yes | |
| Active dependents as a share of the peak | 1 | crates.io database dump | Yes | |
| Binary downloads per release | Not measured | Yes |
MaintenanceLatest human commit: 30 days ago3 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Latest human commit | 2026-10-10 | GitHub repository | Yes | |
| Latest release | 2026-10-10 | crates.io database dump | Yes | |
| First release | 2026-01-12 | crates.io database dump | Yes | |
| Latest version | 1.8.5 | crates.io database dump | Yes | |
| Days the oldest outside issue waits for a reply | 251 | GitHub repository | Yes | |
| Maintainer replies over 365 days | 0 | GitHub repository | Yes | |
| Repository archived | false | GitHub repository | Yes | |
| Repository gone | false | GitHub repository | Yes | |
| Release commit or manifest in the repo | true | crates.io package | Yes | |
| Published docs | true | crates.io database dump | Yes | |
| Latest release fails cargo check | Not measured | Yes | ||
| Build check date | Not measured | Yes | ||
| Build check toolchain | Not measured | Yes |
SecurityUnpatched vulnerabilities: none
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Unpatched vulnerabilities past the grace window | none | RustSec advisory database | Yes | |
| RustSec unmaintained advisory | none | RustSec advisory database | Yes | |
| Deprecation notice | none | crates.io database dump | Yes | |
| Deprecated requirement | none | crates.io database dump | Yes |
Distribution53 releases, 256 downloads over 30 days5 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Releases | 53 | crates.io database dump | Yes | |
| Downloads over 30 days | 256 | crates.io database dump | Yes | |
| Binary downloads over the last 3 releases | Not measured | Yes | ||
| Homebrew installs on request over 365 days | Not measured | Yes | ||
| Repology repository families | Not measured | Yes | ||
| Docker pull growth over 90 days | Not measured | Yes | ||
| Docker pulls at the growth baseline | Not measured | Yes | ||
| Every version a prerelease | false | crates.io database dump | Yes | |
| Every version 0.0.x | false | crates.io database dump | Yes | |
| Every version yanked | false | crates.io database dump | Yes | |
| Crate deleted from crates.io | false | crates.io database dump | Yes |
Repository610 stars, 67 forks, 21 contributors, 765 commits. Stars alone never qualify a project.
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| GitHub stars | 610 | GitHub repository | Yes — one part of the repository route | |
| GitHub forks | 67 | GitHub repository | Yes — one part of the repository route | |
| Contributors with a GitHub account | 21 | GitHub contributors | Yes — one part of the repository route | |
| Commits on the default branch | 765 | GitHub repository | No | |
| Repository's main crate left out of the entry | none | crates.io database dump | Yes |
Facts that never count
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| License | Apache-2.0 | crates.io database dump | No | |
| Runs on, from listed crates and their direct dependencies | CUDA | crates.io database dump | No | |
| What shows each backend | CUDA: next-plaid feature cuda (dependency cudarc), colgrep feature cuda, next-plaid-cli feature cuda, next-plaid-onnx feature cuda | crates.io database dump | No | |
| Native code, from listed crates and their dependencies | Binds native code: tree-sitter, libsqlite3-sys, ort-sys, tree-sitter-language, zstd-sys and 4 more | crates.io database dump | No | |
| Python bindings, from direct dependencies of listed crates | Has Python bindings: next-plaid-onnx needs Python only with feature python | crates.io database dump | No | |
| Crates that depend on a listed crate directly | 1 | crates.io database dump | No |
Corrections and review history
No correction applies to this entry.
Judgments
A judgment enters only through an approved issue and a merged pull request.
No judgment applies to this entry.