Skip to content

perf: CLI cold start is 21s+ — performance sprint needed #435

Description

@laynepenney

Problem

synapt recall search takes 21-27 seconds from the CLI, even for simple queries. This makes the CLI unusable for demos, scripts, and quick lookups. The MCP server doesn't have this problem because it stays warm.

Breakdown (48,700 chunks, 263MB recall.db)

Phase Time %
Python startup + imports ~2s 9%
Embedding model load (all-MiniLM-L6-v2, 22M params) ~12s 55%
SQLite chunk loading (48K rows → Python objects) ~5s 23%
Actual search (FTS5 + scoring + formatting) ~2s 9%
Output rendering ~0.5s 2%

The search itself is fast. The 21 seconds is all overhead.

Proposed Performance Sprint

P0 — Immediate impact

Lazy chunk loading
Don't load all 48K chunks into memory. FTS5 returns matching rowids — only materialize the chunks that match. This alone could drop the 5s chunk loading to <100ms for typical queries.

Embedding server / persistent process
The MCP server already keeps the model warm. For CLI use, either:

  • Ship a tiny embedding daemon that starts on first use and stays alive
  • Use ONNX runtime (3-5x faster model load)
  • Cache embeddings in SQLite so the model is only needed for new/unseen queries

Suppress HuggingFace HTTP noise
Every CLI invocation makes 20+ HTTP HEAD requests to check model freshness. Set HF_HUB_OFFLINE=1 after first download, or use TRANSFORMERS_OFFLINE=1.

P1 — Structural improvements

Index sharding by time
48K chunks in one DB is fine for search but slow for full-table scans. Shard by month/quarter so only recent shards are loaded by default. Older shards searched on demand.

Precomputed search cache
For the MCP recall_quick path: cache the top-N results for common query patterns (status queries, file lookups). Invalidate on new session ingest.

Profile-guided optimization
Add --profile flag to CLI that outputs timing breakdown per phase. Use this to catch regressions.

P2 — Future-proofing

Performance regression tests
CI tests that assert:

  • CLI search completes in <5s for indexes up to 50K chunks
  • MCP recall_quick responds in <500ms
  • Index build completes in <60s for 50K chunks
  • Embedding model loads in <3s (ONNX) or is pre-warmed

Benchmark tracking
Track CLI response time across versions in evaluation/ — same pattern as LOCOMO benchmarks but for latency. Plot over time, alert on regression.

Scaling targets

Chunks CLI target MCP target
10K <3s <200ms
50K <5s <500ms
200K <10s <1s
1M <15s <2s

Context

Discovered during demo recording (2026-04-02). A 21-second recall search makes the "aha moment" demo impossible — viewers won't wait. The MCP path is fine for agent use, but the CLI is the first thing a new user tries after pip install synapt.

First impressions matter. A 21-second CLI search kills adoption.

Related

  • Demo recording: demo/aha-moment.tape
  • Embedding model: sentence-transformers/all-MiniLM-L6-v2 (22M params, ~80MB on disk)
  • Recall DB: .synapt/recall/index/recall.db (263MB for 48K chunks)

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions