Claude Native (Grep/Glob) vs index1 vs qmd — Complete performance comparison of three search tools at different scales
| Data Source | Details | Confidence |
|---|---|---|
| index1 Measured | This project 17,725 chunks / 1,707 docs / 185MB database, median of multiple runs | High (Measured) |
| ripgrep Benchmark | Official burntsushi/ripgrep repo README benchmarks (Linux kernel, ~1GB corpus) | High (Official) |
| SQLite FTS5 | sqlite.org official docs + andrewmara.com 18M-row trigram benchmark | High (Official+Third-party) |
| sqlite-vec | alexgarcia.xyz official v0.1.0 release benchmark (SIFT1M/GIST500K) | High (Author Published) |
| Ollama embed | collabnix.com embedding model guide + nomic.ai official blog | Medium-High |
| qmd Pipeline | tobi/qmd source analysis + component benchmark projection (no official benchmark) | Medium (Projected) |
| Scale Projection | Linear/logarithmic extrapolation from measured baseline based on O(N)/O(log N)/O(N*D) complexity | Medium (Projected) |
Regardless of which AI Agent you use (Claude Code, Cursor, Cline...), every search requires reading the returned results.
The more results returned, the slower and more expensive for AI to read.
| Metric | index1 | qmd |
|---|---|---|
| Tokens per Search | ~460 tok | ~900 tok |
| AI Reading Time | < 0.1s | ~0.2s |
| Search Latency (End-to-End) | ~100 ms | ~1,200 ms |
| 20 Searches Cumulative | 9,200 tok | 18,000 tok |
| 200K Window Usage | 4.6% | 9% |
| AI Cost (20 searches / $3/M) | $0.03 | $0.05 |
MEASUREDCost estimated at Claude Sonnet $3/M input tokens
| Dimension | Claude Native | index1 | qmd |
|---|---|---|---|
| API Calls per Search | 1 call (Grep) | 1 call (docs_search) | 1-3 calls (must choose search/vsearch/query) |
| APIs AI Must Understand | 3 (intuitive) | 1 unified endpoint | 6 tools |
| Index Initialization | Not needed | 1 step:index1 index | 2 steps:bun run index + bun run vector |
| Environment Auto-diagnosis | N/A | ✓ index1 doctor --fix | ✗ |
| 💰 Single Query Tokens | ~36,000 tok (high-frequency words) | ~460 tok (Top-5) | ~900 tok (Top-10) |
| Search Latency (Perceived) | < 50 ms | ~100 ms | ~1,200 ms (query full pipeline) |
| When Ollama Unavailable | N/A | Auto-fallback to text-only search | Vector search completely unavailable |
Grep("search")docs_search("搜索怎么工作的")search("search")→ mediocre resultsquery("search")→ waits 1.2sAll tools connect to AI Agents via MCP protocol. Claude Native is built-in, requiring no additional setup.
| AI Agent | MCP Support | Claude Native | index1 | qmd | Notes |
|---|---|---|---|---|---|
| Claude Code | ✓ Native | Built-in | ✓ 1 endpoint | ✓ 6 tools | index1: one docs_search handles all |
| OpenClaw | ✓ MCP | Built-in | ✓ | ✓ | Open-source Claude Code alternative, native MCP |
| Cursor | ✓ MCP | Built-in (different impl) | ✓ | ✓ Must choose tool | Cursor's AI tends to select fewest tools |
| Windsurf | ✓ MCP | Built-in | ✓ | ✓ | MCP stdio mode |
| Cline | ✓ MCP | Built-in (VS Code) | ✓ | ✓ | VS Code extension, MCP support |
| Aider | ✗ | Built-in grep | Manual integration needed | Manual integration needed | No native MCP support yet |
| GitHub Copilot | Partial | Built-in | Requires Agent Mode | Requires Agent Mode | Copilot Agent Mode supports MCP |
index1's1 unified endpointdesign lets all AI Agents hit the right result in one call, without understanding the differences between multiple tools. qmd's 6 tools (search/vsearch/query/get/multi_get/status) increase the AI's decision burden.
| Capability | Claude Native | index1 + bge-m3 | qmd |
|---|---|---|---|
| Chinese Tokenization | N/A (literal matching) | ✓ jieba precise tokenization pip install index1[chinese] |
✗ porter unicode61 Splits by Unicode character, no semantics |
| Embedding Model | N/A | bge-m3 1024d BAAI multilingual model, CJK optimized |
embeddinggemma 300M English-focused, severe CJK semantic loss |
| CJK Query Strategy | N/A | Dynamic weighting CJK detected → BM25=0.2 / Vec=0.8 |
Fixed weights Language-agnostic, no adaptation |
| Cross-lingual Search | ✗ Literal match only | ✓ Chinese query finds English code "配置合并" → config.py merge() |
Limited Weak model semantics |
| Japanese / Korean | ✗ | ✓ bge-m3 native support Vector search works, BM25 needs extra tokenizer |
✗ |
| Configuration | Model Size | Vector Dimensions | Memory Usage | Index Speed (10K) | Storage (10K) |
|---|---|---|---|---|---|
| index1(BM25 only) | 0 | N/A | ~80 MB | ~10 s | ~60 MB |
| index1 + Ollama nomic-embed-text 768d |
274 MB | 768d | ~600 MB | ~10 min | ~150 MB |
| index1 + Ollama + bge-m3 bge-m3 1024d · CJK optimized |
~1.2 GB | 1024d | ~900 MB | ~14 min | ~200 MB |
| qmd embeddinggemma 300M + 2 GGUF |
~2.2 GB (3 models) | 768d | ~2.5 GB | ~8 min | ~80 MB |
| Query Example | index1 BM25 Result | qmd BM25 Result |
|---|---|---|
"搜索功能" |
search.py, cli.py (precise) | No results or random matches |
"配置合并" |
config.py merge() (precise) | No results |
"search function" |
search.py (normal) | search.py (normal) |
MEASURED Based on actual search tests on the index1 source project
·
CODEqmd FTS5 config source:store.ts:519
pip install index1[chinese]index1 config embedding_model bge-m3index1 index --force
store.tsmodel URI inMEASURED bge-m3 model size ~1.2GB (BAAI/bge-m3) · MEASURED1024d vectors vs 768d: +33% storage, +40% indexing, +15% search latency
| Tool | Index Strategy | 10K Docs | 50K Docs | 100K Docs | Source |
|---|---|---|---|---|---|
| Claude Native | No indexing needed | 0 s | 0 s | 0 s | MEASURED |
| index1 | FTS5 inverted index | ~10 s | ~30 s | ~60 s | PROJECTED |
| index1 + Ollama | FTS5 + Ollama embedding | ~10 min | ~45 min | ~90 min | PROJECTED@9K tok/s |
| qmd | FTS5 + GGUF embedding | ~8 min | ~35 min | ~70 min | PROJECTED |
| Tool | Storage Content | 10K | 50K | 100K |
|---|---|---|---|---|
| Claude Native | None (scans source files) | 0 MB | 0 MB | 0 MB |
| index1 | FTS5 index + original text | ~60 MB | ~250 MB | ~500 MB |
| index1 + Ollama | FTS5 + 768d vectors | ~150 MB | ~600 MB | ~1.2 GB |
| qmd | FTS5 + vectors + llm_cache | ~80 MB | ~350 MB | ~700 MB |
| Tool | Memory Composition | 10K | 50K | 100K |
|---|---|---|---|---|
| Claude Native | ripgrep process + file buffer | ~50 MB | ~150 MB | ~400 MB |
| index1 | Python + SQLite page cache | ~80 MB | ~150 MB | ~250 MB |
| index1 + Ollama | Python + SQLite + Ollama model | ~600 MB | ~700 MB | ~800 MB |
| qmd | Bun + SQLite + 3 GGUF models | ~2.5 GB | ~2.7 GB | ~3.0 GB |
REFERENCE ripgrep 9.5M files = ~400MB RSS (burntsushi/ripgrep#1823) · REFERENCEOllama nomic-embed-text ~500MB resident
| Tool / Mode | Formula | 10K Docs | 50K Docs | 100K Docs |
|---|---|---|---|---|
| Claude Native(Grep) | ripgrep_scan |
30-50 ms | 150-250 ms | 300-500 ms |
| index1 + Ollama | BM25 + embed + vec + RRF |
~60 ms | ~90 ms | ~120 ms |
| index1 | BM25 + RRF |
< 5 ms | ~8 ms | ~15 ms |
| index1Cache Hit | L1 cache lookup |
< 1 ms | < 1 ms | < 1 ms |
| qmdsearch (BM25) | FTS5 only |
< 5 ms | ~8 ms | ~15 ms |
| qmdvsearch (Vector) | embed + vec |
~30 ms | ~65 ms | ~90 ms |
| qmdquery (full pipeline) | expand + BM25 + vec + RRF + rerank |
~1,200 ms | ~1,250 ms | ~1,300 ms |
| qmdCache Hit | llm_cache lookup |
~5 ms | ~5 ms | ~5 ms |
| Query | Engine Time (Cold) | Engine Time (Hot) | CLI Total Time | Grep Comparison |
|---|---|---|---|---|
"中日韩"(low-frequency, 46 lines) | 576 ms | 94 ms | 0.21s | 0.43s (Grep slower) |
"embedding"(mid-frequency, 257 lines) | 119 ms | 85 ms | 0.20s | 0.24s (close) |
"search"(high-frequency, 950 lines) | 100 ms | - | 0.22s | 0.21s (tied) |
"config"(very high-frequency, 4386 lines) | 119 ms | - | 0.24s | 0.18s (Grep faster) |
"搜索是怎么工作的"(CJK semantic) | 91 ms | - | 0.20s | Grep can't do semantic search |
"向量搜索的实现原理"(CJK semantic) | 89 ms | - | 0.21s | Grep can't do semantic search |
"how does search work"(EN semantic) | 332 ms | - | 0.44s | Grep can't do semantic search |
"how to configure watch paths" | 228 ms | - | 0.34s | Requires 2-3 Grep combinations |
"search"Query Token Consumption| Scale | Grep Matched Lines | Claude Native (Grep) | index1 (Top-5) | qmd (Top-10) | index1 Savings |
|---|---|---|---|---|---|
| Current (64 files) | 950 linesM | ~36,000 tokensM | ~460 tokensM | ~900 tokens | 98.7% |
| 10K Documents | ~15,000 linesP | ~375,000 tokens | ~460 tokens | ~900 tokens | 99.88% |
| 50K Documents | ~60,000 linesP | ~1,500,000 tokens | ~460 tokens | ~900 tokens | 99.97% |
| 100K Documents | ~120,000 linesP | ~3,000,000 tokens | ~460 tokens | ~900 tokens | 99.98% |
M= Measured,P= Projected from word frequency density. Claude context window is 200K tokens, searching "search" at 100K docs via Grep requires15 fullwindows to fit the results.
| Query | Frequency Type | Grep Matched Lines | Grep Tokens | index1 | qmd | index1 Savings |
|---|---|---|---|---|---|---|
中日韩 |
Rare word | ~1,000 | ~25,000 | ~460 | ~900 | 98.2% |
embedding |
Mid-frequency | ~30,000 | ~750,000 | ~460 | ~900 | 99.94% |
search |
High-frequency | ~120,000 | ~3,000,000 | ~460 | ~900 | 99.98% |
config |
Very high | ~500,000 | ~12,500,000 | ~460 | ~900 | 99.99% |
import |
Extremely high | ~800,000 | ~20,000,000 | ~460 | ~900 | 99.99% |
Grep consumption is orders of magnitude larger (10K project 250K tok / 100K project 2.4M tok), incomparable — only index1 vs qmd shown here.
| Feature | Claude Native | index1 | qmd |
|---|---|---|---|
| Runtime | Rust (ripgrep) | Python 3.10+ | Bun (TypeScript) |
| Search Algorithm | Literal match + regex | BM25 + Vector + RRF | BM25 + Vector + QE + RRF + Rerank |
| BM25 Full-text Search | ripgrep (not BM25) | ✓ FTS5 | ✓ FTS5 |
| Vector Semantic Search | ✗ | ✓ sqlite-vec | ✓ sqlite-vec |
| Embedding Engine | N/A | Ollama (local) | node-llama-cpp (local GGUF) |
| Default Embedding Model | N/A | nomic-embed-text 768d (default) bge-m3 1024d (CJK optimized) | embeddinggemma-300M (English only) |
| Model Ecosystem & Extensibility | |||
| Available Models | N/A | Ollama ecosystemHundreds | GGUF format only |
| Model Switching | N/A | One command:index1 config embedding_model xxx | Edit source code with GGUF URI |
| Model Presets | N/A | 5 presets (lightweight / standard / chinese / multilingual / high_precision) | No presets, 3 hardcoded models |
| Chinese Model Switching | N/A | ollama pull bge-m3One-click switch | Must find GGUF Chinese model yourself |
| Hot Model Switching | N/A | ✓ Change config + index --force | ✗ Requires recompile/restart |
| Query Expansion | ✗ | ✗ | ✓ Fine-tuned 1.7B GGUF |
| LLM Reranking | ✗ | ✗ | ✓ qwen3-reranker 0.6B GGUF |
| RRF Fusion | ✗ | ✓ k=60 | ✓ k=60 + position-aware |
| Query Cache | ✗ | ✓ L1/L2 (10min TTL) | ✓ llm_cache (SQLite) |
| MCP Tools | 3 (Grep/Glob/Read) | 5 | 6 |
| Chunking Strategy | None (full text) | 5 language-aware (md/py/rs/js/txt) | Markdown chunking (800 tok/chunk) |
| Supported File Types | All text files | .md .py .rs .js .ts .jsx .tsx .txt | .md (Markdown) |
| CJK Optimization | ✗ | ✓ Dynamic weighting BM25=0.2/Vec=0.8 | ✗ |
| Web UI | ✗ | ✓ Flask (port 6888) | ✗ |
| File Watching | ✓ Real-time | ✓ watcher | ✗ |
| Auto-diagnosis (doctor) | N/A | ✓ | ✗ |
| External Service Dependency | None | Ollama (optional) | None |
| Cross-platform | macOS/Linux/Windows | macOS/Linux/Windows | macOS/Linux (Bun) |
| AI Editor / Agent | Claude Native | index1 | qmd |
|---|---|---|---|
| Claude Code | ✓ Built-in | ✓ MCP stdio | ✓ MCP stdio |
| Cursor | ✓ Built-in | ✓ MCP stdio | ✓ MCP stdio |
| Windsurf | ✓ Built-in | ✓ MCP stdio | ✓ MCP stdio |
| Cline(VS Code) | ✓ Built-in | ✓ MCP stdio | ✓ MCP stdio |
| OpenClaw | ✓ Built-in | ✓ MCP stdio | ✓ MCP stdio |
| CLI / Scripts | ✗ No standalone CLI | ✓ index1 search |
✓ bun run search |
| Platform | index1 | qmd |
|---|---|---|
| macOS(ARM / Intel) | ✓ pip / pipx | ✓ bun |
| Linux(x64 / ARM) | ✓ pip / pipx | ✓ bun |
| Windows | ✓ pip / pipx | ⚠ Bun Windows support limited |
| Docker | ✓ | ✓ |
| Dimension | Claude Native | index1 | qmd |
|---|---|---|---|
| Search Speed (Small Scale) | ★★★★★ | ★★★★☆ | ★★☆☆☆ |
| Search Speed (Large Scale) | ★★☆☆☆ | ★★★★☆ | ★★★☆☆ |
| Search Precision | ★★★☆☆ | ★★★★☆ | ★★★★★ |
| Token Efficiency | ★★☆☆☆ | ★★★★★ | ★★★★☆ |
| Semantic Understanding | ★☆☆☆☆ | ★★★★☆ | ★★★★★ |
| CJK / Multilingual | ★☆☆☆☆ | ★★★★☆ | ★★☆☆☆ |
| Ease of Use / Zero Config | ★★★★★ | ★★★★☆ | ★★★☆☆ |
| Resource Consumption | ★★★★★ | ★★★☆☆ | ★★☆☆☆ |
| Code File Support | ★★★★★ | ★★★★☆ | ★★☆☆☆ |
| Large-scale Scalability | ★★☆☆☆ | ★★★★☆ | ★★★★☆ |
| Cross-platform Compatibility macOS / Linux / Windows | ★★★★★ macOS / Linux / Windows | ★★★★★ macOS / Linux / Windows | ★★★☆☆ macOS / Linux (Win limited) |
| 🤖 AI Agent Usability | ★★★★☆ | ★★★★★ | ★★☆☆☆ |
| 🏆 Total Score | 40 / 60 | 50 / 60 | 37 / 60 |
No single tool wins across all dimensions. The recommended strategy is tochoose based on project scale and query type:
< 1K files:Claude Native is sufficient, no extra tools needed.
1K-10K files:Claude Native (exact lookup) + index1 (semantic/CJK queries).
10K-100K files:index1 as primary (99%+ token savings), Grep only for known identifiers.
Large English doc libraries:qmd (highest precision) + Grep (quick lookup).
Multilingual code projects:index1 (the only one supportingCJK optimization+ 5 language chunkers).