Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Memory and limits

What is resident

StructureGrows withNotes
Trigram posting listsdistinct trigrams × filesRoaring bitmaps; run-optimised after a build
Symbol tablesdefinitionsper file, restored from the saved index
Reference tablescall sites and type mentionsnames interned once; positions packed
Dependency graphresolved importsbidirectional, with cached dependent counts
File storefilesone small entry per file; content is not kept
Mapped contentfiles > 1 MiB read by searchesthe “mapped” figure in the UI; released when a file is removed

Small files are read into owned buffers per access and dropped afterwards, so search traffic does not accumulate memory. The CI corpus (6,237 files, 38.9 MB) sits at about 120 MB resident after a build.

Limits that protect the server

LimitValueWhere
Page size1 to search.max_page_size (1,000); default search.default_page_size (50)max
Offset≤ search.max_page_offset (100,000)offset; deeper pages are refused
Files readbest first; search.fast_rank_files (no limit by default), up to search.max_fast_rank_files on requestmax_files
Match budgetsearch.min_match_budget (32,768) to search.max_match_budget (100,000), search.match_budget_multiplier (8) × page end; about 230 bytes per match while a search runsstops the scan; reported as truncated_by_budget and limits_hit
Deadlinetimeout_ms or just under request_timeout_secsthe scan stops on its own even if the HTTP response was abandoned
Context lines≤ search.max_context_lines (10) per hit (/api/context: ≤ 200)context
Concurrent searchesmax_concurrent_searches, shared by REST and gRPCbeyond it: 503 / RESOURCE_EXHAUSTED immediately
Regexcompiled size and DFA size limitsabsurd patterns are a 400
Per-file hitssearch.per_file_matches (1,000) per document per search, its best by score; the budget from result 1000 onkeeps a broad regex bounded
File sizemax_file_size (default 10 MB)larger files are not indexed
WebSocket frames4 KiB inbound/ws/progress ignores inbound data

When a limit cuts a search short, the response names it in limits_hit (max_files, match_budget, per_file_cap, timeout or indexing, each with a sentence for people). gRPC sends the names in the fcs-limits-hit response header, fcs prints them on stderr, and MCP adds a “Results capped” line, so a capped result never passes for a complete one.

None of these need tuning for normal use; they exist so a bad query or an abandoned client cannot pin the machine. The defaults are measured; see Search limits. MCP’s own limits are in [mcp] (search_code 50 hits by default, at most 1,000, paged with offset).