Benchmarks that you can rerun

Agent-memory vendors publish numbers; ours come with the script, the dataset, the named model, and a sha256 signature over the result set. Everything below is generated from committed reports in the open repo. If you cannot reproduce a number, it comes down.

Feature matrix

Architecture facts, not adjectives. Competitor rows come from their public repos (Zep / Graphiti · Mem0 · Cognee · Letta); anything we could not verify is "n/a".

Perseus VaultZep / GraphitiMem0CogneeLetta
Temporal modelFull SQL:2011 bi-temporal (valid + transaction time, point-in-time recall)Bi-temporal edges (Graphiti)TimestampsTimestampsTimestamps
Storage / deploymentSingle local binary, SQLite, offlineServer + graph DBServer or SaaS, vector DBServer, graph + vector DBsServer, Postgres
Encryption at restAES-256-GCM built inn/an/an/an/a
Audit trailHash-chained journal (keyed MAC under encryption; external review pending)n/an/an/an/a
Retrieval modesFTS5 keyword + dense vector + hybrid RRF, decay + trust weightedGraph + semanticVectorGraph + vectorVector + recall memory
LicenseMITApache-2.0 (Graphiti)Apache-2.0Apache-2.0Apache-2.0

Retrieval recall (LongMemEval)

Session-level recall against the 500-instance LongMemEval split (23,867 sessions ingested into the real binary, offline, judge-free; default hybrid retrieval). perseus-vault.exe.

84.6%
recall@1
95.2%
recall@3
97.4%
recall@5
99.2%
recall@10
0.903
MRR
source: benchmark/longmemeval/report.json sig 9babb85f54f9

End-to-end QA vs Zep

Zep publishes 63.8% on LongMemEval with GPT-4o (their paper). Ours below: identical split, pinned answerer and judge named in the report, LongMemEval's official per-type judge prompts. The headline is the mean of 3 independent signed runs (73.6% / 75.0% / 72.8%); the worst run scores +9.0 points vs Zep's published number. Where conditions differ from a competitor's published run, the comparison is flagged, not blended. Per-type table is from the primary run's signed report.

73.8%
mean of 3 independent full runs (range 72.8–75.0%, gpt-4o-2024-08-06)
79.0%
with LongMemEval's official CoT answer prompt (answer_prompt: official-cot) — mean of 3 independent signed full runs (range 78.4–80.0%)

The benchmark ships two official answer prompts (plain and step-by-step CoT); both distributions above are 100% official methodology and differ only in that flag — each number carries its answer_prompt, recorded in the signed report. Zep's publication does not state which variant they used, so the comparison is flagged, not blended.

question typecorrectaccuracy
knowledge-update60/7876.9%
multi-session84/13363.2%
single-session-assistant56/56100.0%
single-session-preference9/3030.0%
single-session-user67/7095.7%
temporal-reasoning92/13369.2%
source: benchmark/longmemeval/qa_report.json sig 929623670d8b

Same-box recall, all systems fully local

Every system stood up and run live on one H100 against the same local Ollama (qwen2.5:14b-instruct + nomic-embed-text): identical fact set, identical queries, identical substring judge. No published or cloud numbers are substituted for a competitor. Cells show recall accuracy and p50 latency.

systemrecallp50 latencystack
Perseus Vault (hybrid)1.0035.6 mssingle local binary, in-process
Letta (archival / pgvector)1.00135.5 msserver + Postgres/pgvector
Mem0 (vector)0.6037.9 msPython + Qdrant
Zep (Graphiti temporal KG)0.2049.7 msserver + Neo4j

Letta matches Perseus Vault on recall for this corpus; the difference is operational, an in-process binary answering in ~35 ms versus a server plus Postgres at ~135 ms p50. Zep's self-hosted Community Edition server is deprecated and its zep_python memory API is now Zep Cloud only, so this measures Zep's open-source engine, Graphiti (a temporal knowledge graph on Neo4j), with entity extraction and embeddings both on the same local Ollama. Building a knowledge graph needs an LLM to do structured extraction, and a local model is lossy at it (5 entities and 2 edges from 6 facts here), so 0.20 reflects local-extraction quality rather than Zep Cloud, which uses frontier models. The point of this table is not a scoreboard; it is what each architecture does when the whole stack has to run locally.

Scale and latency

The real binary over MCP stdio, seeded corpus, 100 queries per metric. Hardware named in the report: Windows 11, 16 cores. Bi-temporal point lookups stay flat from 10K to 100K entities; that column is the differentiator.

entitieswrite sustained fts5 p50/p99dense p50/p99hybrid p50/p99as_of p99cold start
10,000479/s3.14 / 9.62 ms11.96 / 14.29 ms19.03 / 24.56 ms0.53 ms56.6 ms
100,00040/s15.67 / 23.23 ms25.43 / 32.78 ms79.73 / 92.86 ms0.46 ms58.2 ms
source: benchmark/scale/report.json sig c688a8490cc1

Temporal correctness

Bi-temporal reconstruction checked scenario by scenario: what was believed at T (transaction time), what was true at T (valid time), and the full cell. Deterministic, offline.

100.0%
gauntlet: 13/13 checks
10/10
valid_at
1/1
as_of
2/2
bitemporal
100.0%
temporal suite: 20/20
source: benchmark/temporal/report.json sig 009c4c3e25cb

Correctness and determinism at scale (BEAM)

Named for BEAM (Beyond a Million Tokens), which tests at 128K / 500K / 1M / 10M tokens to defeat the "dump everything in context" cheat. Our claim is orthogonal to a context-window score: FTS5 + deterministic bi-temporal retrieval must not degrade as the corpus grows. BEAM embeds the CI-verified bi-temporal gauntlet (the same 13 checks) inside a filler corpus sized to each token tier and asserts, at every tier, that correctness holds (13/13), that two independent runs produce an identical signature (deterministic=true), and that point lookups stay flat. Fully offline, lean FTS5 + bi-temporal binary (no embeddings), on Linux / Unraid.

100.0%
gauntlet: 13/13 at every tier (128K–10M)
deterministic=true
identical signature across two runs, every tier
23.07 ms
as_of p50 at 10M (flat from 22.08 ms at 128K)
10M
153,846 entities, ~10.1M tokens, 332.43s populate
token tierfiller entitiesapprox tokenspopulategauntletdeterministicas_of p50/p95valid_at p50/p95
128K1,969129,4612.87 s13/13yes22.08 / 24.36 ms22.75 / 25.61 ms
500K7,692505,74910.21 s13/13yes21.26 / 24.45 ms17.7 / 24.11 ms
1M15,3841,011,49827.58 s13/13yes23.17 / 88.83 ms22.09 / 23.95 ms
10M153,84610,115,374332.43 s13/13yes23.07 / 24.61 ms22.62 / 25.56 ms

Point-lookup p50 is flat (22.08 → 21.26 → 23.17 → 23.07 ms as the corpus grows 128K–10M), because lookups are (category,key)-indexed. p95 is flat too except a single 88.83 ms sample at the 1M tier, shown as measured; every other tier stays under 26 ms. 40 samples per axis per tier.

source: benchmark/beam/report.json sig 2c1e38ab18aa · methodology

Reproduce every number

Every report above is generated by a script in the repo and signed with a sha256 over its result set. From a clean clone:

git clone https://github.com/Perseus-Computing-LLC/perseus-vault.git
cd perseus-vault
cargo build --release
python benchmark/recall/run.py        # recall quality (offline)
python benchmark/longmemeval/run.py   # LongMemEval retrieval (offline)
python benchmark/temporal/gauntlet.py # bi-temporal gauntlet (offline)
python benchmark/scale/run.py         # scale + latency (offline)
python benchmark/beam/run.py --tiers 128K 500K 1M 10M --out /tmp/beam.json  # BEAM: correctness + determinism at scale (offline)
python benchmark/longmemeval/qa.py    # end-to-end QA (needs an OpenAI key; prints cost first)

This page was generated by scripts/gen_benchmark_page.py at commit eb8bc17. If a number here cannot be traced to a committed signed report, that is a bug; please file it.