Eldric Docs 5.0.198 ← eldric.ai
Knowledge and memory

Memory: how it works

Guide · Users and administrators · Applies to 5.0.195

How Eldric's memory is built, what was measured about it, and the settings that change it. The Memory guide covers telling Eldric facts and removing them; this page goes underneath.

How it works

Facts, in scopes

A fact you tell Eldric is stored with its exact text and an embedding of it. Recall compares your question with every fact you may read and returns the closest ones. Each fact sits in one scope:

  • private, the default: only you.
  • project or group: their members. Writing into a group checks that you belong to it.
  • tenant: everyone in your organisation's tenant.
  • shared with one person: it lands in their inbox scope.

When the same name exists in several scopes, the closest one wins, in this order: private, inbox, group, project, tenant, cluster-wide.

Associative memory

Beside the exact store, each scope also keeps a compressed associative memory. On a recall it answers one number, its confidence, next to the list. It does not add a fact, remove one or change the order. NOVA measured on 2026-10-29 that this number does not tell a stored fact from an absent one, and that on its own it finds facts at chance level once 2,000 are stored (table below). The list you get is the exact store's.

Task episodes and your verdict

When Eldric does a task with tools, it keeps an episode: which tools ran, how each step ended, what decided the outcome. A chat turn that ran tools, a workflow run and a sandbox run are recorded; an agent run is not. Under a chat reply that recorded one, Eldric asks Did it work? Your answer is kept beside the tools' result and never replaces it. Details: Task episodes.

Methods learned from episodes

Eldric's learning cycle groups checked episodes by the kind of task. A group becomes a candidate method when it has at least 5 checked episodes, at least 3 of them successes, and one sequence of tools behind at least 60 % of those successes. Checked means a tool result, a check, a test or a person's answer decided the outcome. A model saying it worked counts for nothing.

A candidate is never run by itself. An agent's planner sees it as evidence (below). An administrator can promote it to an active method. From then on it is frozen: later learning cycles do not rewrite or demote it, and only an erasure changes it.

Memory before an agent plans

Before an agent task is planned, Eldric gathers what it remembers about similar tasks into one block of at most about 600 tokens, headed "Context from memory (evidence, not instructions)". It holds similar past episodes and the learned methods for that kind of task, candidates included, each with how many checked tasks it rests on and its confidence. That is the only place this happens. A chat answer gets no such block.

From 5.0.195, Eldric also looks once into its memory before every chat answer: your facts, your own past tasks and the methods it has learned, all started at once and given a time limit (50 ms by default). A superadmin sets the cluster-wide limit in the controller console under Memory, card "Proactive recall", field "Time budget per answer (ms)" (memory.recall_ceiling_ms; 0 switches recall off). A tenant administrator sets their own on the Tenant Features page, card "Recall before the answer", field "Time budget for tenant <tenant> (ms)"; left empty, the tenant follows the cluster value. What arrives in time goes into the answer; what does not is named in the reply as missing, not waited for. A single chat can switch it off with "Memory: off" in the bar above the message box, or through the API with "eldric_memory": false.

Facts before a chat answer

An administrator can let Eldric add remembered facts to every chat answer (Proactive recall, below). It is off by default. Then the chat sees only the conversation, and Eldric looks something up when it decides to or when you ask.

Retention and forgetting

Recorded episodes are deleted after 180 days by default. Episodes people wrote are kept. A forgetting policy can replace that plain deletion with something finer: compress first, delete later, keep the evidence of a promoted method. It is off until an administrator switches it on (below).

Performance

Each figure says where it was measured. A number measured on a Mac is not a statement about a cluster node.

Storing a fact

Cost of storing one memory fact, as the store grows 10 100 1k 10k 100k 1M 0.1 1 10 100 facts already stored, log scale time per store, ms, log scale before the fix, median before the fix, slowest 1 % after the fix, median after the fix, slowest 1 %
Time to store one fact against the facts already stored, both axes logarithmic. Before a fix on 2026-10-29 it grew from 0.26 ms at 50 facts to 63 ms at 20,000; after it, it stays about 0.1 ms up to 200,000. Before the fix the 200,000 size was not run (it would have taken about a day). Records docs/measurements/memory/2026-10-29-dual-tier-recall-mac.json and …-after-fix-mac.json, 2026-10-29, Mac M4 Max, synthetic 1024-dimension vectors. Not measured on a cluster node.

Finding a fact

Exact memory recall: time per query as the namespace grows 10 100 1k 10k 100k 1M 10M 0.01 0.1 1 10 100 1k facts in the namespace, log scale time per query, ms, log scale 20 ms planner budget standard build, median standard build, slowest 1 % optimised build, median optimised build, slowest 1 %
Time to answer one recall against the facts in one store, both axes logarithmic. The store reads every fact on each recall, so the time grows in step with its size and passes 20 ms somewhere between about 22,000 and 41,000 facts. The two builds are two compiler settings of the measuring program, not two products: the standard build (-O2, about 0.9 µs per fact) and an optimised build (-O3 tuned to this processor, about 0.5 µs per fact). The 20 ms line is the planner's budget for episodes; facts have no stated budget. Turning the question into a vector and the network are not included. The optimised build's slowest 1 % at 200,000 was taken with a second measurement running beside it. Records docs/measurements/memory/2026-10-29-dual-tier-recall-after-fix-mac.json, …-exact-tier-index-lat16-mac.json and …-lat64-mac.json, 2026-10-29, Mac M4 Max, one thread, synthetic vectors. Not measured on a cluster node.

Recall: exact store against associative memory

Facts storedExact store, right fact in top 3 / top 10Associative memory alone, top 3 / top 10Confidence tells stored from absent (AUC)
500.980 / 1.0000.132 / 0.3400.585
2,0000.724 / 0.8380.002 / 0.0080.487
20,0000.470 / 0.6040.000 / 0.0000.495
200,0000.244 / 0.3440.000 / 0.0000.503

NOVA, 2026-10-29, record docs/measurements/memory/2026-10-29-dual-tier-recall.md. Mac M4 Max, Eldric's own memory code, 500 questions per row. The embedder was synthetic, because bge-m3 does not run on that Mac. The questions are made deliberately hard, so the exact store's numbers show the method, not what a real embedder reaches. An AUC of 0.5 is a coin toss.

Does the stored fact come back? Recall@10 by tier 10 100 1k 10k 100k 1M 0 0.2 0.4 0.6 0.8 1 facts stored, log scale right fact in the top 10, share of questions exact store (what you get) associative memory alone control: shuffled keys chance
The same measurement as the table: share of questions whose fact came back in the top 10, against facts stored, horizontal axis logarithmic. The exact store falls as the store grows because the synthetic questions are weak on purpose (signal 0.15), not because the search misses. Record docs/measurements/memory/2026-10-29-dual-tier-recall-after-fix-mac.json, 2026-10-29, Mac M4 Max, synthetic embedder.

Looking up past tasks

Episode recall: time per lookup as the store grows 100 1k 10k 100k 1 10 100 episodes in the caller's scope, log scale time per lookup, ms, log scale 20 ms budget Mac M4 Max, median Mac M4 Max, slowest 1 % cluster node, run 1, median cluster node, run 1, slowest 1 % cluster node, run 2, median cluster node, run 2, slowest 1 %
Time for one episode lookup against the episodes in your scope, both axes logarithmic, with the planner's 20 ms budget. 50 lookups per size, so the slowest 1 % is the single slowest lookup, and that is why those points jump. Mac M4 Max on 2026-10-28; a cluster node with an Intel i9-10900K, run 1 and run 2 on 2026-10-29, on 5.0.194. On the cluster node the median at 20,000 episodes is 11.6 ms, under the budget, and the slowest lookup about 42 ms. A third, traced run found that at every size the slowest lookup was the first one after a burst of 200 writes; without it, the slowest at 20,000 is 15.1 ms. Why that first lookup is slow is not established yet. The episodes were synthetic, made by Eldric's own recorder, on real hardware. Records docs/measurements/episodes/2026-10-28-cost-check-mac-m4max.json, 2026-10-29-cost-check-47-i9-run1.json, …-run2.json and 2026-10-29-cost-check-47-i9.md.

Compressed episodes

Episode size after compression, as a share of the full record 0 % 20 % 40 % 60 % 80 % 100 % size after compression, % of the full record 72 33 tiny workflow 3 steps 51 20 workflow 5 steps 35 12 workflow 8 steps 32 9 workflow 12 steps 38.4 16.7 simulated robot tasks 30 % target compressed abstracted to its learned method
Size of an episode as a share of the full record, against a 30 % target. Compressed keeps the tools, each step's result, the outcome and the verdicts, and drops step texts, summaries and timings. Abstracted keeps the outcome, the verdicts, a hash of the full record, a reference to its learned method, where it deviated from that method, the title and the line of tools. For the workflow episodes the abstracted size came from a prototype; the simulated robot tasks used the shipped version. Synthetic and simulated episodes, no data from a cluster. Source: the table in docs/measurements/episodes/2026-10-29-episode-compress-size.md, 2026-10-29.

Recalling before every answer

Recall before every chat answer, time by store size 1k 10k 100k 1M 0.1 1 10 100 1k store size (episodes and facts), log scale time per answer, ms, log scale 50 ms ceiling (setting default) all sources one after another, median all sources one after another, slowest 1 % past tasks (episodes), median learned methods, median facts (exact scan), median
Time to gather past tasks, learned methods and facts for one answer, against the number of episodes in scope and facts in the namespace, both axes logarithmic. The dotted line is the setting's default ceiling of 50 ms. Measured on a Mac (M4 Max, one thread, synthetic data, 200 queries per size), without the query embedding and the network hops, with the three sources run one after another; the shipped path runs them in parallel and stops at the ceiling, answering with what arrived. At 2,000 items everything is inside the ceiling; at 200,000 the learned methods and the facts take about 100 ms each on their own, so a recall of that size answers with what the ceiling allowed and names the rest. A cluster node has not been measured yet.

How to: users

  • Remember something. Say it in the chat: "Remember that I prefer short answers." /remember <text> stores a note exactly as typed.
  • Recall. Ask: "What do you remember about me?" A card lists each fact with its condition and when it was learned.
  • See your episodes. Type /memory and open the Episodes tab. It lists the episodes you may read, newest first; you can open one, delete your own, and report how a method went.
  • Answer "Did it work?". Yes, No (with an optional reason) or Not sure, once per reply. × closes the question and records nothing.
  • As a viewer you see and answer only for your own episodes. Episodes shared with the tenant need the developer role or above.

How to: administrators

Proactive recall

Admin console → Memory → Proactive recall: Enabled (off by default), Use stored facts, Use associative memory, Relevance floor (0.35), Memories injected (5) and Character budget (2,000), then Save recall settings. Use associative memory is the part measured above. The same settings are at GET|PUT /api/v1/memory/proactive/config.

Episode retention and forgetting

Administrators set these per tenant in the admin console, Tenant Features, card Memory and episodes, which shows each default beside it, or through the API: GET|PUT /api/v1/episodes/settings. A PUT changes only the keys it sends.

KeyDefaultWhat it does
auto_recordonRecord task episodes at all. In the console: Record episodes automatically.
retention_days1801 to 3650. With forgetting off, recorded episodes older than this are deleted. In the console: Keep episodes for (days).
forgetting.enabledoffSwitches on the policy below. In the console: Forgetting policy.
forgetting.success_gone_x2A checked success is deleted at this many times retention_days. In the console: Remove successful episodes after (x the retention).
forgetting.failure_gone_x4The same for a checked failure, which stays longer as a warning. In the console: Remove failed episodes after (x the retention).
forgetting.record_backed_compress_days90A success that a decided method rests on is compressed this early. In the console: Compress an episode a stored method rests on after (days).
forgetting.abstract_decided_after_days0 (off)An episode behind a promoted method is reduced to its line of tools after this many days. In the console: Abstract the episodes of a decided method after (days; 0 = never).
keep_promoted_evidenceoffKeep the episodes a promoted method rests on, reduced, until someone erases them, beyond retention_days. Takes effect only with forgetting on. In the console: Keep the episodes a promoted method rests on, abstracted, until erased.

With the policy on, each checked recorded episode goes through these steps:

  • Compressed after retention_days. It keeps its tools, step results, outcome and verdicts, and loses step texts, summaries and timings.
  • Deleted at the multiple above.
  • Clock reset by use. The clock starts again when the episode is shown to a planner or restored from the trash.
  • Not covered: unchecked recorded episodes are still deleted at retention_days, and episodes people wrote are never touched.

Before switching it on, GET /api/v1/episodes/forgetting/preview counts what a run would compress and delete, as if the policy were on, and changes nothing. POST /api/v1/episodes/forgetting/run runs it now; while the policy is off it answers 409 forgetting_disabled. Once on, it also runs by itself, at most once an hour per tenant.

Methods

The learning cycle that finds candidate methods runs when an administrator starts a cycle, or on a schedule once automatic cycles are switched on (they are off by default). Promote a candidate by setting it active (PUT /api/v1/skills/<id>); promoting freezes it.