LanceDB index rebuild speed from git
LanceDB index rebuild speed from git: enabling stateless deployment
- LanceDB write operations take under 30ms even at 1000 documents; the embedding model accounts for 99%+ of cold-start rebuild time at every tested corpus size
- BAAI/bge-small-en-v1.5 loads from disk cache in 0.68s; the model file is 133 MB, giving a first-download load time of ~2.25s from HuggingFace Hub on a typical connection
- BGE-small-en-v1.5 embeds at ~34.5ms/doc for short synthetic texts but ~177ms/doc for real research items; BERT's O(n²) attention cost means document length — not document count — is the primary driver of embedding time
- At the current corpus size of 61 items with full Markdown text, cold-start rebuild takes 11.5s with BGE-small, already exceeding the 5–10s target and with no improvement path as the corpus grows
- Pre-computed embeddings stored as JSON in git (7.74 KB per 384-dim document) load and write into LanceDB in under 0.2s for 1000 documents, making startup time effectively O(1) with respect to corpus size
- JSON storage cost for pre-computed BGE-small embeddings is 7.74 MB for 1000 documents; for a personal research corpus of 200–300 items, this is under 2.5 MB, an acceptable git repository size
- all-MiniLM-L6-v2 is approximately 2× faster than BGE-small at embedding (16.4ms/doc vs 34.5ms/doc for short texts) but does not change the fundamental scaling failure: at 500 real research items, MiniLM would still require over 20s to rebuild
- GitHub code search is rate-limited to 10 requests per minute, is keyword-only with no semantic understanding, and may return incomplete results for large queries; it is not a viable replacement for vector search and only useful as a supplementary lexical search layer
Research Question
Can the LanceDB index be rebuilt from the .md files in the repo on startup fast enough to enable stateless (per-request) deployment? Measure rebuild time at: current corpus size, 100 files, 500 files, 1000 files. Is the embedding model load time (BAAI/bge-small-en-v1.5) the bottleneck or the LanceDB write operations? Would a lighter embedding model (e.g. MiniLM) or pre-computed embeddings stored in git change the equation?
Findings
(Populated from §6 Synthesis above.)
Executive Summary
The embedding model — not LanceDB — is the bottleneck in cold-start index rebuilds: LanceDB write operations consume under 1% of total startup time at all tested corpus sizes. BAAI/bge-small-en-v1.5 takes 11.5s to rebuild the current 61-item research corpus from Markdown text (10.8s embedding, 0.68s model load), already exceeding the 5–10s target. Pre-computed embeddings stored as JSON in git reduce startup to under 0.2s regardless of corpus size, making stateless deployment viable immediately. Model2Vec (identified in prior semantic-search research as ~200× faster than MiniLM on CPU) would enable per-request rebuild without pre-computed storage and should be evaluated as the production embedding model.
Key Findings
-
LanceDB write operations take under 30ms even at 1000 documents; the embedding model accounts for 99%+ of cold-start rebuild time at every tested corpus size. [high]
-
BAAI/bge-small-en-v1.5 loads from disk cache in 0.68s; the model file is 133 MB, giving a first-download load time of ~2.25s from HuggingFace Hub on a typical connection. [high]
-
BGE-small-en-v1.5 embeds at ~34.5ms/doc for short synthetic texts but ~177ms/doc for real research items; BERT's O(n²) attention cost means document length — not document count — is the primary driver of embedding time. [high]
-
At the current corpus size of 61 items with full Markdown text, cold-start rebuild takes 11.5s with BGE-small, already exceeding the 5–10s target and with no improvement path as the corpus grows. [high]
-
Pre-computed embeddings stored as JSON in git (7.74 KB per 384-dim document) load and write into LanceDB in under 0.2s for 1000 documents, making startup time effectively O(1) with respect to corpus size. [high]
-
JSON storage cost for pre-computed BGE-small embeddings is 7.74 MB for 1000 documents; for a personal research corpus of 200–300 items, this is under 2.5 MB, an acceptable git repository size. [high]
-
all-MiniLM-L6-v2 is approximately 2× faster than BGE-small at embedding (16.4ms/doc vs 34.5ms/doc for short texts) but does not change the fundamental scaling failure: at 500 real research items, MiniLM would still require over 20s to rebuild. [high]
-
GitHub code search is rate-limited to 10 requests per minute, is keyword-only with no semantic understanding, and may return incomplete results for large queries; it is not a viable replacement for vector search and only useful as a supplementary lexical search layer. [high]
-
Model2Vec (potion-base-8M), identified in prior semantic-search research as ~200× faster than MiniLM on CPU with 91–93% of MiniLM's MTEB accuracy and no PyTorch dependency, would reduce rebuild time to under 1s for 500 items — making per-request stateless rebuild viable without pre-computed embedding storage. [medium — requires direct LanceDB benchmark to confirm]
Assumptions
- Assumption: GitHub Actions runner hardware is representative of free-tier deployment targets. Justification: GitHub Actions 2-core runners are comparable to Fly.io free tier CPU; RAM (7 GB vs 256 MB) differs and may slow PyTorch model load on memory-constrained targets.
- Assumption: Document content truncated to 2000 characters per file represents a reasonable upper bound for embedding input length in this corpus. Justification: Research items are structured Markdown; semantic content is front-loaded in title, executive summary, and key findings.
- Assumption: Pre-computed JSON embeddings would be committed alongside
.mdfiles as part of theadd_memorywrite path. Justification: The natural implementation; any other approach (separate batch job) introduces synchronisation complexity between stored files and their embeddings.
Analysis
The benchmark data makes a clear recommendation. The rebuild-from-text approach fails the target at the current corpus size and degrades further as the corpus grows — there is no configuration of the current stack (batch size, model choice within bge/MiniLM family) that fixes this without switching to a fundamentally faster embedding approach.
Pre-computed embeddings eliminate the bottleneck at the cost of a model-version coupling constraint (all stored embeddings must be regenerated if the model changes). For a single-owner personal project, this cost is low and manageable. The storage overhead (~2.5 MB for 300 items) is negligible in git terms.
Model2Vec represents a possible third path — one that avoids both the storage overhead of pre-computed embeddings and the latency of bge-small/MiniLM. Given that prior research already recommends Model2Vec for Phase 2 of the semantic search system, evaluating it for the LanceDB rebuild path simultaneously would be efficient. The recommendation is to pursue both paths in parallel: implement pre-computed embeddings as the near-term fix (eliminates the latency problem immediately), and benchmark Model2Vec against LanceDB as an input to the production embedding model decision.
Risks, Gaps, and Uncertainties
- Model2Vec's rebuild time in the LanceDB context has not been directly benchmarked; the 200× speedup is well-sourced but measured in a different evaluation context.
- Fly.io free tier (1 vCPU, 256 MB RAM) may exhibit worse model load times than the GitHub Actions runner due to RAM pressure during PyTorch initialisation.
- The pre-computed JSON approach requires a code change to
mcp_server.pythat is not implemented; the benchmark demonstrates feasibility, not production readiness. - JSON float precision (default Python repr) may introduce minor rounding differences vs the model's native float32 output; this is unlikely to affect retrieval quality but has not been tested.
Open Questions
- What is Model2Vec (potion-base-8M) actual rebuild time for the current 61-item research corpus? Should become a backlog item for the Memory-System.
- Should embeddings be stored as JSON (human-readable, diffable in GitHub web UI) or numpy binary (5× smaller)? Decision depends on operational tooling preferences.
- How should the
add_memorywrite path inmcp_server.pybe modified to persist embeddings as a JSON sidecar alongside each.mdfile? This is the concrete implementation question for W-0015. - What is the RAM footprint of Model2Vec on a 256 MB Fly.io instance during inference?
sources
- [x]
Research/completed/2026-03-02-agent-memory-management-context-injection.md— MemoryOS three-tier hierarchy; startup latency as design constraint - [x]
Research/completed/2026-03-02-semantic-full-text-search.md— semantic search and embedding model selection findings - [x] LanceDB docs
- [x] LanceDB Python API (Table, add, search)
- [x] BAAI/bge-small-en-v1.5 model card
- [x]
sentence-transformers/all-MiniLM-L6-v2model card - [x] GitHub code search API (as zero-rebuild alternative)
- [ ]
2026-03-08-self-hosted-mcp-server-options.md— deployment options that depend on this benchmark (backlog, not yet researched) - [ ]
davidamitchell/Memory-SystemBACKLOG.md W-0015 — the corresponding discovery item that this research informs