# TemporalStore: A disruptive open-source engine managing your LLM memory

> Source: <https://temporalstore.ai/blog-context-management.html>
> Published: 2026-08-15 20:51:41+00:00

**TemporalStore** replaces that with a small, ranked, source-backed

**ContextPack**: on a real agent history it answered every question better while sending a tiny fraction of the tokens. And because memory lives in the engine — not the prompt — it persists

**across sessions, devices, agents, and your whole team**, something point-in-time retrieval over one transcript can't do. Open source, self-hostable. Come build it with us →

[github.com/matrixarkai/TemporalStore](https://github.com/matrixarkai/TemporalStore).

## The usual approach: append everything, every turn

The typical way to give an agent memory is the simplest one: on each new turn, append
*all* of the prior context — the earlier prompts *and* the model's own intermittent output —
back into the next input window, and send it again.

It works, so it ships. But it has two quiet problems.

**Most of what you re-send is noise.** A lot of that appended history — especially the
*intermittent output*: tool results, logs, stack traces, file dumps — was useful for a single step
and then just sits in the window, re-sent every turn, diluting the signal the model actually needs now.
You pay for it on every call, and it crowds out the few lines that matter.

**And nothing is learned.** It's all trapped in one session — there's no cross-session
memory, and no long-term profile that gets *better* as the history deepens. The agent never
accumulates what it figured out about the user, the project, or the decisions already made; when the
window rolls or the session ends, it starts from zero.

So you pay more (re-sending a growing, noisy transcript) and remember less (nothing survives the session). That's the trap.

## The "solution" that becomes its own stack

So you add retrieval. Reasonable instinct. But watch what "agent memory" quietly turns into in production:

- a
**vector database** to store, version, and semantically search the embeddings, - a
**summarization / extraction pipeline** to compress old turns into something retrievable, - and a
**memory service** to glue it together, decide scope, and rank — usually a bespoke one.

Three systems, and you're *still* replaying transcripts on the side. Three things to run, monitor,
and keep consistent — all to answer one small question on every turn: *what does this agent actually
need in front of it right now?*

The bet behind TemporalStore is that agent memory is one temporal problem — and deserves one temporal engine, not a stitched-together stack.

It's open source (Apache-2.0), Rust-native, runs from a single Docker command, and ships with reproducible benchmarks instead of adjectives. Here's how it works, and why the numbers land.

## The core idea: send a ContextPack, not a transcript

The design draws one clean line. Your model reasons and extracts; the engine remembers and serves.

```
# the flow — you own the model, TemporalStore owns the memory
raw query / event / resource + hints
  → extract intent, time, filters, entities   (your runtime, or MatrixArk)
  → store compact serving records             (TemporalStore)
  → retrieve a token-budgeted ContextPack     (TemporalStore)
  → final LLM  =  local context  +  ContextPack
  → the answer becomes tomorrow's memory
```

Notice what TemporalStore **doesn't** do: it never calls an LLM or an embedding model.
Your harness — or a managed runtime like **MatrixArk**
([matrixark.ai](https://matrixark.ai)) that sits on top — produces the vectors and structured
intent. TemporalStore stores them and does the fast, bounded work at serving time.

That work produces the whole point of the system: a compact, **source-backed**
`ContextPack`

. Not a transcript — the few hundred tokens that actually matter for *this*
query, each traceable to the event that produced it.

**And it denoises.** Remember all that re-sent intermittent output? TemporalStore ingests
it as compact records — the tool call kept as a short marker, the bulky result head-truncated or
summarized — so the pack carries the *fact* the tool produced, not the noisy blob. Less noise in the
window is itself better answers: the model isn't rummaging through stale logs to find the one line that
mattered.

## What you get, in one line each

The payoff up front — the mechanism behind each one is the rest of this piece:

**Fewer tokens at equal-or-better quality**— a bounded ContextPack instead of a transcript that grows every turn.** Better answers, less hallucination**— time-valid memory with replayable, source-backed citations.** Low serving latency across millions of entities**— work bounded by the filtered candidate set, not the corpus.** Exact recall, no vector DB**— a controlled candidate set scored exactly; ANN's lossiness never enters the picture.** Team-wide memory**— cross-session, cross-device, cross-agent, and auditable by construction.** One engine, self-hosted**— Apache-2.0, one Docker command, no LSM write-amp on the append path.

## Why a small pack beats "replay the newest N tokens"

This is the counterintuitive part, so let's prove it instead of asserting it.

Take a **real** working set: a developer's full local coding history, tool calls included —
**12,384 events, 97 sessions, ~1.7M tokens**. Ask six real questions about it. Run two arms
through the *same* reader model and the *same* judge:

**Replay**— feed the full local history, newest-first, up to the model's window.** Managed**— retrieve a token-budgeted`ContextPack`

.

| Metric | Full replay | TemporalStore pack | Result |
|---|---|---|---|
| Tokens the model works from | 1,698,940 | ~1,333 | 99.9% fewer |
| Answer quality (judge, 0–10) | 6.59 | 8.30 | +1.71 |
| Questions won or tied | — | 6 / 6 | every one |

Now the *why*, which is more interesting than the headline.

**The pack wins by the widest margin on the questions whose answers live in old history** —
`q_storage`

10.0 vs 6.05, `q_parity`

8.05 vs 5.25. It wins by the smallest margin
when the newest messages happened to already be on-topic.

That gradient *is* the mechanism, made visible: recency-truncated replay literally cannot see the
old-but-relevant facts that ranked retrieval surfaces. **You pay for 1.7M tokens and still get the
worse answer.**

**And it holds up on the standard memory benchmarks.** On **LoCoMo** and
**LongMemEval_s** — the two public long-term-memory suites the field measures agent recall
against — TemporalStore's tree-plus-index retrieval lands **hit@k 0.995–1.00**. And in a
head-to-head on one shared open-source stack (a `qwen2.5:7b`

reader, MiniLM embeddings,
Claude-judged), it **ties** an OpenViking-style baseline — a reimplementation of
[VikingMem](https://arxiv.org/abs/2605.29640), the memory system that reported state-of-the-art
in its own paper — on short LoCoMo chats (~83–84%) and
**wins long-horizon LongMemEval outright — 98% vs 66%** answer accuracy. So the token
savings above aren't bought with worse recall: the pack is small *and* it finds — and answers —
the right evidence.

## Memory that's shared — not stuck in a session

Here's the differentiator that matters most for real teams, and it's easy to miss under the token math.

A transcript is trapped in one session. The moment the window rolls or the tab closes, it's gone. That's
the true ceiling on agent memory — not how much you can stuff into one prompt, but whether anything survives
*between* prompts, *between* agents, *between* people.

Because TemporalStore keeps memory in the engine — ingested once, indexed by scope
(`tenant → user → session → agent → resource`

) — recall isn't bound to the current thread. An
agent can remember what *another* agent learned yesterday, what the user decided on a
*different device*, what the *team* agreed last month. And because every recalled fact is
timestamped and traceable to its source event, shared memory stays **auditable** — a citation,
not a rumor.

Cross-session, cross-device, cross-agent, cross-teammate — by construction. That's the memory a single-transcript retriever structurally cannot give you.

## The serving innovation: a database's serving path, aimed at memory

Most "agent memory" libraries are a thin wrapper over a vector index. TemporalStore is built like a database — and that shows most in the serving path. Three roles, disaggregated:

**Proxy**— the front door: routing, request batching, backpressure.** Metaserver**— placement, leases, the shard map. It decides*where*data lives; it's off the hot read path.**Datanodes**— the workers: a write-ahead log for durability, the model executors, the in-memory indexes that answer reads.

**Retrieval is not a brute-force vector scan.** Context is a tree — tenant → user → session
→ resource → entity. A query walks it layer by layer, using compact **secondary indexes** to
prefilter *before* reading any timeline. Filters compose by **intersecting posting lists**
— status ∩ project ∩ time-bucket — so a query touches a bounded set of events, not the whole corpus. Only
then does it score, apply temporal decay, and pack to budget.

The payoff: **latency stays low even across millions of entities**, because the work per
query scales with the *filtered* set, not the dataset. ContextPack retrieval runs
**~17 ms p95** at a 1.2k-token budget.

## The storage innovation: append-structured and temporal

Underneath is a storage engine built around one fact: **memory is temporal.** Data arrives
in time order, is queried by time, and cools with age. That shapes every layer.

**Append-structured.** Writes append; nothing mutates in place, and the engine reloads
crash-safe from its own write-ahead log. When the segmented log once re-parsed itself on every append (an
O(n²) trap — append #200 took 100+ ms), a per-node cursor made it O(1): **109 ms →
2.2 ms**, with the on-disk format byte-identical so live stores reload with zero migration.

**Real tiering — eviction and promotion.** Hot data sits in memory; as the working
set outgrows the budget it's evicted down through cache to SSD and shared storage. The part most systems
get wrong:

**cold data is promoted back into memory on read.** A multi-user harness proves it — a deliberately tiny memory budget to force eviction, then cold reads to force promotion:

**256k reads, zero mismatches**, partition isolation intact, up to 81 users and 187k writes.

**Compute/storage separation.** The same code runs three ways — **local**
(one node), **Raft-replicated**, or **shared-storage** — so you start on a laptop
and scale to a disaggregated cluster where compute and storage grow independently, atop two self-contained
Apache-2.0 libraries: [ MatrixCache](https://github.com/matrixarkai/MatrixCache)
(caching) and

[(replication). For the shared-storage tier at scale, stateless datanodes read and write one durable object store —](https://github.com/matrixarkai/MatrixRaft)

**MatrixRaft****MatrixObject**, the enterprise object store engineered for extreme-performance shared storage — so compute can scale for traffic spikes without copying every shard to every node.

## Why no vector database

RAG usually runs on a vector DB doing *approximate* nearest-neighbor (ANN) search over a giant
flat pile of embeddings — trading recall for speed, because scoring every vector exactly is too expensive.
TemporalStore never gets there. Its **layered virtual file system** and compact
**secondary indexes** filter most candidates out first — by scope, type, entity, and time — so
by the time we rank, the set is small and we score it **exactly, with no ANN loss** (that's the
hit@k 0.995–1.00 above). That same scoped tree doubles as a **virtual file system** for
*resources, skills, and memory* — one time-aware namespace instead of a separate store for each — so
it's also one fewer system to run and keep in sync.

## Why no RocksDB (no LSM)

Temporal memory is *append-heavy* — you're constantly writing new timestamp-keyed events — which
is exactly what an LSM like RocksDB handles worst: compaction keeps rewriting data it already wrote
(**write amplification**), with tail-latency spikes and stop-the-world pauses. TemporalStore's KV is
shaped for it: a key's *value* is a run of **timestamp-keyed values appended in order**,
so an event is an append onto an existing value — not a flood of new keys to merge and re-sort. The result:
**far less write amplification than RocksDB**, no compaction, no pauses.

[temporalstore.ai](https://temporalstore.ai)and the

[Tech & Infra deep dive](https://temporalstore.ai/temporalstore.html), with reproducible methodology at

[temporalstore.ai/benchmarks.html](https://temporalstore.ai/benchmarks.html).

## Try it in two minutes

No Rust toolchain on your host — it builds inside the image:

```
git clone https://github.com/matrixarkai/TemporalStore.git
cd TemporalStore
docker compose -f docker-compose.single-node.yml up --build
```

You get a metaserver on `127.0.0.1:17101`

and a datanode on `:17102`

. Whole
dependency list: Docker and a clone.

Prototyping one session with a few docs? A plain vector index is fine — TemporalStore earns its place when memory has to persist across sessions, agents, and a team, stay sharp at millions of events, and stop you re-sending a growing transcript every turn.

## Two invitations

### 🛠️ If you build on temporal data — come build with us.

Whether you want to serve your own **temporal use cases** on TemporalStore, layer a
**context system** on top of it, or dig into the **innovative Rust core** —
Raft replication, the multi-layer cache, and the append-structured storage engine — there's real,
open work here. Apache-2.0, and small enough to actually get into.

[⭐ Star & build on GitHub](https://github.com/matrixarkai/TemporalStore)

### 📉 If you run agents in production — cut this line-item.

A bounded, ranked **ContextPack** cuts context cost sharply *while raising answer
quality*, and folds a stack of separate memory services into one self-hosted engine. It also gives
agents **team-wide, cross-session memory** — every recalled fact traceable to its source,
and no data ever leaves your boundary.

[Pilot it on your workload →](https://temporalstore.ai)
