CortexDB Docs
Operations

Recall Tuning

Every recall-strategy knob — graph retrieval, HyDE, multihop, salience, reranker, and the constants that aren't (yet) configurable.

CortexDB's recall pipeline can run several retrieval channels and fuse them with reciprocal rank fusion. About a dozen env vars expose knobs into that pipeline; another two dozen are compiled constants tuned against LongMemEval-S and LoCoMo.

Most deployments shouldn't tune any of these — the defaults match the published 93.8% number.

Names on this page are verified; the default values are not

Every variable below was checked against the shipped v0.9.8 and v0.9.9 binaries, and the ones that aren't read are called out where they appear. The default values, though, are inherited from the v1 documentation: they are compiled numeric constants, so they don't surface in the boot-time config_lint dump (which covers a different set of variables) and can't be read back from a running server. Treat them as indicative. If a specific value matters to your deployment, confirm it with an A/B rather than relying on the number printed here.

What runs by default vs what's full capability

On a default self-hosted instance, recall runs BM25 + vector + RRF fusion only — verified via diagnostics: "full" (only recall.bm25_search, recall.vector_search, recall.fusion fire). The six channels below describe the full capability: the Graph BFS channel needs the knowledge graph (CORTEX_ENTITY_GRAPH=1 + enrichment), and the cross-encoder reranker needs a Cohere key. The entity-name / synonym / temporal channels are internal to fusion. See Self-hosting defaults.

The pipeline at a glance

Query
  ├─► Query routing ─────────────────────────► question_type
  ├─► (optional) HyDE multiquery expansion ──► N hypothesized passages → query vectors
  ├─► (optional) Multihop query planner ─────► M follow-up queries (LLM)
  ├─► Parallel retrieval channels:
  │      • Vector (HNSW)            [default]
  │      • Fulltext (BM25 + WordNet)[default]
  │      • Entity-name (exact/fuzzy)
  │      • Synonym
  │      • Graph BFS (KG edges)     [needs KG + enrichment]
  │      • Temporal (recency + decay)
  ├─► Reciprocal rank fusion (RRF, k=60) ──► fused candidate list
  ├─► Cross-encoder rerank (optional) ──► reranked top-K  [needs Cohere]
  └─► Build response pack (citations, beliefs, episodes)

Skipping a stage saves latency at the cost of recall accuracy.

Graph retrieval

The KG channel walks edges around entities mentioned in the query.

Env varDefaultWhat it controls
CORTEX_GRAPH_RETRIEVAL_DISABLE(unset)Set =1 to skip the graph channel. ~-3–5 pp on multi-session.
CORTEX_GRAPH_RETRIEVAL_TOP_K40 (single) / 120 (multi)Graph-derived candidates passed to fusion.

Disable on the voice/realtime hot path (trade ~-3 pp for ~150 ms); bump TOP_K to 80/240 for entity-rich queries. Non-overridable constants: GRAPH_RETRIEVAL_MAX_ENTITIES = 48, GRAPH_RETRIEVAL_MAX_EDGES = 512, GRAPH_RETRIEVAL_MAX_EPISODES = 256, GRAPH_WEIGHT = 0.20.

HyDE multiquery expansion

HyDE asks an LLM to write a hypothetical passage that would answer the query, then embeds that instead of (or with) the literal query.

Env varDefaultWhat it controls
CORTEX_HYDE_PASSAGES_MS1Hypothetical passages for multi-session queries. 0 disables HyDE for multi-session.
CORTEX_HYDE_MULTIQUERY_DISABLED_TYPESmulti-session,open-domainQuestion types where HyDE is off.

Set the disabled-types list to all four types to disable HyDE entirely (saves ~150–400 ms, loses ~1–2 pp on phrasing-mismatch queries). CORTEX_HYDE_PASSAGES_MS=3 uses temperatures [0.3, 0.6, 0.9] for wider coverage at 3× HyDE cost.

Multihop query planner

For complex queries, an LLM plans 2–N follow-up queries, then runs all of them through retrieval.

Env varDefaultWhat it controls
CORTEX_MULTIHOP_QUERY_PLANNER_DISABLE(unset)Set =1 to disable multihop entirely.
CORTEX_MULTIHOP_QUERY_PLANNER_TYPESmulti-session,open-domainTypes where multihop runs.
CORTEX_MULTIHOP_QUERY_COUNT4Follow-up queries the planner generates.
CORTEX_MULTIHOP_MAX_QUERY_FANOUT5Cap on simultaneously executing planned queries.
CORTEX_MULTIHOP_COVERAGE_ORDER_DISABLE(unset)Use LLM-emitted order instead of coverage-optimal reordering.

Empty the types list for latency-sensitive deployments (saves 1–3 LLM round-trips, loses ~1–3 pp on complex multi-session); QUERY_COUNT=6 + FANOUT=8 for offline QA.

Salience prior

A per-memory importance score updated by access patterns; the ranker can use it as a recency prior.

Env varDefaultWhat it controls
CORTEX_SALIENCE_WEIGHT0.10Weight of salience in final ranking. Range [0.0, 1.0].
CORTEX_AUTO_ROUTE(unset)Set =1 to auto-pick per-type salience weights.

Bump to 0.20 for "recently relevant" agents; set 0.0 for historical-archive workloads (the right answer might be years old).

Recency ordering

Salience is a prior on ranked retrieval. order=recency is different — it replaces ranked retrieval for the events layer with a timeline tail: the scope's newest events by observed_at, rendered newest-first. Set it explicitly on /v1/recall or /v1/answer, or let /v1/answer infer it for "recent/latest" questions. It's the right tool for "what's the latest…" reads, where relevance ranking returns the most-repeated items and can drop the newest ones.

Env varDefaultWhat it controls
CORTEX_RECENCY_TAIL_EVENTS100Tail size when the request sets no budgets.per_layer_limits.events.
CORTEX_RECENCY_ORDER(on)Set =0 to disable the recency mode entirely — an explicit order=recency then falls back to ranked retrieval.
CORTEX_RECENCY_INFERENCE(on)Set =0 to stop /v1/answer auto-inferring recency for recency-shaped questions (an explicit order still applies).

Verified: recency needs the holistic view

On v0.9.9 the timeline tail is applied in holistic view (the recall default). In granular / raw views order=recency is a no-op — events return oldest-first and an events cap keeps the oldest N. For "latest X" reads, keep the default view.

Entity-vector seeding

Take the query's entity mentions, look up their canonical vectors, use those as additional query vectors.

Env varDefaultWhat it controls
CORTEX_ENTITY_VECTOR_SEED_ENABLE(unset)Set =1 to enable. Off by default.
CORTEX_VECTOR_POSTFILTER_OVERFETCH(compiled)Overfetch multiplier so the scope post-filter still hits K.

The variable is POSTFILTER, not TENANT

The v1 docs called this CORTEX_VECTOR_TENANT_OVERFETCH. That name is not read by the server — verified against the shipped v0.9.8 and v0.9.9 binaries, which contain CORTEX_VECTOR_POSTFILTER_OVERFETCH instead. Setting the old name has no effect.

Enable for queries with named entities that don't match stored phrasing exactly. Constants: ENTITY_VECTOR_SEED_TOP_K = 10, ENTITY_VECTOR_SEED_MIN_SIMILARITY = 0.40, ENTITY_VECTOR_SPAN_LIMIT = 5, ENTITY_VECTOR_PER_SPAN_TOP_K = 5.

Reranker

A cross-encoder that re-scores the top ~25–40 fused candidates as (query, candidate) pairs.

Env varDefaultWhat it controls
CORTEX_RERANKER_PROVIDER(empty = disabled)cohere or local. Empty disables the reranker.
CORTEX_RERANKER_MODELrerank-v3.5 (Cohere)Model name.
CORTEX_RERANKER_MODEL_PATH(none)Path to a local ONNX model when PROVIDER=local.

cohere + COHERE_API_KEY → ~+2 pp on noisy sets, ~$0.001/recall, +80–200 ms. local + MODEL_PATH → free but ~200–500 ms on CPU. Leave disabled for voice/sub-100ms paths.

Question-type executor switches

The /v1/answer endpoint routes queries through type-specific executors. These flags disable specific paths for A/B testing.

Env varWhat it controls
CORTEX_MS_COUNT_RELEVANCE_ENABLECount-based relevance scoring for multi-session (experimental).
CORTEX_FACT_EVENT_PROMOTION_ENABLEPromote facts to event-level relevance.
CORTEX_FACT_VALIDITY_FILTERFilter recalled facts by bi-temporal validity windows.

Seven switches the v1 docs list do not exist

The v1 page documents a larger table. These names are not read by the server — verified against the shipped v0.9.8 and v0.9.9 binaries, which contain no such string, so setting them does nothing: CORTEX_MS_EXECUTOR_DISABLE, CORTEX_MS_EVIDENCE_PACK_DISABLE, CORTEX_MS_STAGE_C_USE_VERIFIER, CORTEX_MS_RETRY_ON_ABSTAIN, CORTEX_TEMPORAL_EXTRACT_DISABLE, CORTEX_COMPOSITIONAL_ENABLE, CORTEX_ENUMERATE_COUNT_ENABLE. Only the three above are real. (The binary does carry further CORTEX_MS_* switches beyond these — they're internal and undocumented, so they're deliberately not listed here rather than guessed at.)

Default stance: don't touch these

They exist for benchmark tooling to validate routing decisions; the compiled defaults produced 93.8%. Flip one only as a diagnostic with an A/B harness.

Synchronous-write kill switches

These affect the write path — and thus when recall has the data available.

Env varWhat it controls
CORTEX_SYNC_FACT_EXTRACT_DISABLESkip sync fact extraction; all extraction async. Faster writes; recall lags.
CORTEX_SYNC_FACT_EXTRACT_MAX_SESSIONSCap on sessions processed sync per batch.
CORTEX_SYNC_GRAPH_SEED_DISABLESkip sync graph seeding. Same tradeoff.
CORTEX_SYNC_GRAPH_SEED_MAX_BULK_MEMORIES / _MAX_ENTITIESCaps on sync graph seeding.

Disable for batch ingest (see the Batch profile) or write-heavy workloads that tolerate 30–60 s recall lag.

Memory evolution (methylation + consolidation)

Background jobs that prune low-utility memories and consolidate related ones.

Env varDefaultWhat it controls
CORTEX_METHYLATION_INACTIVITY_HOURS168 (7 days)Unaccessed-this-long memories become pruning-eligible.
CORTEX_METHYLATION_MIN_ACCESS10Min access count before pruning-eligible.
CORTEX_METHYLATION_MIN_UTIL_RATIO0.30Min utility-to-access ratio.
CORTEX_METHYLATION_MIN_ACCESSES_FOR_RATIO5Min accesses before the ratio is evaluated.
CORTEX_CONSOLIDATION_MIN_MEMORIES2Min same-entity memories to trigger consolidation.
CORTEX_CONSOLIDATION_MAX_BATCH10Max consolidations per scheduler tick.
CORTEX_CONSOLIDATION_MIN_AGE_HOURS24Memories younger than this aren't consolidated.
CORTEX_CONSOLIDATION_MAX_SURPRISE0.5Don't consolidate memories above this surprise score.

Tighten methylation for chatty agents (INACTIVITY_HOURS=72), loosen for archival (INACTIVITY_HOURS=720); CORTEX_SCHEDULER_DISABLE=1 disables the whole scheduler for stable benchmark evals.

Compiled constants you can't (yet) override

Tuned against LongMemEval-S + LoCoMo; file an issue to request promotion to an env var.

ConstantValueWhat it controls
RETRIEVAL_TOP_K / RETRIEVAL_TOP_K_MS40 / 160Candidates per channel (single / multi-session).
RERANK_POOL / RERANK_POOL_MS25 / 40Top-N passed to the reranker.
RRF_K60.0Smoothing constant in the RRF formula.
GRAPH_WEIGHT0.20Graph channel's fused weight.
GRAPH_RETRIEVAL_MAX_ENTITIES / _EDGES / _EPISODES48 / 512 / 256KG walk caps.
ENTITY_VECTOR_SEED_TOP_K / _MIN_SIMILARITY10 / 0.40Entity-vector seed caps.

Latency budget breakdown (default config)

Rough p50 for a single /v1/recall against a ~100K event scope:

Stagep50Optional?
Query embedding~50 msNo
HyDE multiquery (if enabled)~250 msYes — disable per-type
Multihop planner (if enabled)~400 msYes — disable per-type
Vector + fulltext + KG retrieval (parallel)~80 msNo
RRF fusion~2 msNo
Cross-encoder rerank (if enabled)~150 msYes
Response pack assembly~30 msNo
Total (default, multi-session)~900 ms
Total (voice profile, single-session)~180 ms

HyDE and multihop dominate wherever they run — disabling them is the highest-leverage latency win for voice/realtime.

Next steps

On this page