Performance

Benchmarks

sqry is built for speed at every layer. Key measured numbers:

MetricValueNotes
Graph query latency12–21 msvs 1,300–2,400 ms for embedding-based search (100–200x faster)
JavaScript indexing throughput760K LOC/sMeasured with parallel graph indexing enabled
C++ indexing throughput1.1M LOC/s
Python indexing throughput~500K LOC/s
Cache speedup113x (452 ms → 4 ms)Warm multiprocess-safe AST cache vs cold parse
Fuzzy candidate reduction99.8%Jaccard trigram pre-filter on short queries

The 113x cache speedup applies to repeated queries against an indexed codebase. The first query after sqry index loads the snapshot; subsequent queries (including across processes via the persistent cache) return in 4 ms.


Cache Environment Variables

sqry uses a two-layer cache: an in-memory eviction policy plus a persisted .sqry-cache/ directory. All cache settings are controlled by environment variables.

VariableDefaultDescription
SQRY_CACHE_ROOT.sqry-cacheCache directory location
SQRY_CACHE_MAX_BYTES50 MBMaximum total cache size in bytes
SQRY_CACHE_DISABLE_PERSIST0Set to 1 to disable disk persistence (memory-only; useful in CI/containers)
SQRY_CACHE_POLICYlruEviction policy: lru, tiny_lfu, or hybrid
SQRY_CACHE_POLICY_WINDOW0.20Protected window ratio for TinyLFU and hybrid policies (range: 0.05–0.95)
SQRY_CACHE_DEBUG0Set to 1 to emit CacheStats{...} on stderr without modifying CLI flags

Choosing an eviction policy:


Lexer Pool Tuning

The query lexer uses thread-local buffer pooling to reduce allocations on repeated queries. The defaults work for most workloads.

VariableDefaultDescription
SQRY_LEXER_POOL_MAX4Pool size per thread. Set to 0 to disable pooling entirely.
SQRY_LEXER_POOL_MAX_CAP256Buffer capacity limit in tokens before the pool shrinks a buffer
SQRY_LEXER_POOL_SHRINK_RATIO8Shrink ratio applied when a buffer exceeds SQRY_LEXER_POOL_MAX_CAP

Increase SQRY_LEXER_POOL_MAX for high-concurrency server workloads. Set it to 0 only when micro-benchmarking or when sub-millisecond latency requirements make per-allocation overhead relevant.


Cache Management Commands

# Show cache statistics (hit rates, size, entry counts)
sqry cache stats

# Show cache statistics as JSON (for monitoring/automation)
sqry cache stats --json

# Remove entries older than 30 days
sqry cache prune --days 30

# Cap cache to 1 GB, removing oldest entries first
sqry cache prune --size 1GB

# Preview what would be removed without deleting
sqry cache prune --days 7 --dry-run

# Clear all cached entries (requires --confirm to prevent accidental deletion)
sqry cache clear --confirm

Watch Mode

Watch mode keeps the index current with real-time file monitoring. sqry uses OS-level file system events (inotify on Linux, FSEvents on macOS, ReadDirectoryChangesW on Windows) with a debounce window to coalesce rapid saves.

# Start watching with an initial index build
sqry watch --build

# Show statistics for each incremental update
sqry watch --stats

# Set a custom debounce window in milliseconds (default: 100–400 ms, platform-dependent)
sqry watch --debounce 500

Watch mode is useful during active development: the index stays warm so sqry query returns up-to-date results without a manual sqry update step. Index update latency after a file save is typically under 1 ms for the file-detection step; the graph rebuild time depends on the number of changed files.

The debounce window (--debounce) controls how long sqry waits after the last file event before triggering a rebuild. Lower values give faster updates; higher values reduce redundant rebuilds when many files are saved in quick succession (for example, during a git checkout).


Index Validation

The --validate flag controls what happens when the index snapshot is loaded for queries. It does not run during the build itself.

# Load the index with strict validation; abort on any corruption
sqry index . --validate=fail --auto-rebuild

With --validate=fail --auto-rebuild, sqry will detect corruption when loading the snapshot, automatically trigger a full rebuild, and retry the query. This is the recommended setting for CI pipelines where a corrupted index would otherwise produce silent wrong results.

Other validation levels:

# Warn on validation errors but continue (default)
sqry query --validate=warn "kind:function" .

# Skip validation entirely (fastest, no safety net)
sqry query --validate=off "kind:function" .

Exit codes with --validate=fail: