Skip to content
Memory runtimeOpen-source · Apache 2.0 · self-hosted

Mem0 recalls what's similarStatewave decides what's delivered

Mem0 ranks by relevance and hands you the result. Statewave assembles a deterministic, token-bounded context bundle and returns an integrity-hashed receipt of exactly what the agent saw.

S

ContextAssembler

deterministic · token-bounded

budget 1,180/1,500
ranked context bundle
profile_factprefers succulents, low-waterscore 18.2
procedurerefund flow for orders < 30dscore 15.6
episodeold address on file−4 expired · dropped
receipt01J9Z4··· · sha256:a3f9c1 · bundle:7c21 (enforce)
0.905LoCoMo, n=1,540
4ranking signals, deterministic
708unit tests · 56 evals
0API keys to run
Postgres-only, runs offline

Ranked by similarity, or assembled by policy

Mem0 partitions memory by an id you pass, then ranks what it finds by a blend of vector similarity, keyword overlap and entity matches. Statewave ingests each event as an immutable episode, compiles those into typed memories with confidence and validity, and assembles a ranked bundle the same way on every call.

m0Mem0 · flat identity filters
user_idagent_idrun_idapp_id
vector search →candidate pool, re-scored before return

Retrieval is non-deterministic

The caller picks an id and the store ranks by relevance. Expiry exists but is opt-in with no default, and there is no kind priority and no recency decay — so an address the customer changed months ago, with no expiry set, can still rank above the current one.

SStatewave · Record → Compile → Context → Govern
01Recordimmutable episodes
02Compiletyped memories
03Contextranked bundle
04Governpolicy + receipt
typed memory kinds · ranking priority
profile_fact
10
procedure
8
episode_summary
5
raw_episode
3

Assembly is deterministic and inspectable

Given the same subject, task, and token budget, the assembler returns the identical bundle every run. Four additive signals set the order: kind priority (3–10), recency (0–5), task relevance (0–8), and temporal validity (−4 to +3).

How order is decidedscore = priority + recency + relevance + validity
KIND PRIORITY
3–10
typed profile facts outrank raw episodes
RECENCY
0–5
linear by age, newest scores highest
TASK RELEVANCE
0–8
word overlap (0-5) or cosine similarity (0-8)
TEMPORAL VALIDITY
−4…+3
valid facts gain +3, expired ones lose 4

Where each capability lives

Both are memory layers for agents. They diverge on what the runtime enforces and what you have to build or pay for.

CAPABILITY
m0Mem0
SStatewave
RETRIEVAL & RANKING

How context is selected

m0
Top-k embedding-nearest as the candidate pool, then re-scored
S
Deterministic assembly, additively scored to a token budget

Ranking signals

m0
Vector similarity fused with keyword and entity boosts; optional reranker
S
Kind priority, recency, task relevance, temporal validity

Stale / expired facts

m0
Optional expiry, off by default; no confidence score or decay
S
Penalised −4 and dropped before assembly

Same query, same result

m0
Varies with the index
S
Byte-identical bundle every run
GOVERNANCE & PROVENANCE

Proof of what the agent saw

m0
None
S
Immutable, ULID-addressable receipt with an integrity hash

Policy on the read path

m0
Implement it in your app
S
Declarative bundles: deny or redact by label and caller

Provenance to source

m0
Session ids automatic; links to source documents by hand
S
Source episode ids, confidence, and validity per memory

Subject deletion (GDPR)

m0
One call per subject; change history is retained
S
One call clears episodes, memories, and receipts
OPERATIONS & LICENSING

Storage

m0
Pluggable vector stores
S
Postgres and pgvector, nothing else to run

Graph / relationship memory

m0
OSS: graph config removed, relations no longer returned. Platform: graph affects the score, no graph payload to query
S
Typed memories with provenance, no graph tier

Interface

m0
Python and TypeScript SDKs, REST, CLI, hosted MCP server
S
REST, Python and TypeScript SDKs, MCP server, connectors

License

m0
Apache 2.0 core, paid platform
S
Apache 2.0 throughout, runs fully offline

Mem0 v3 deleted the open-source graph-store drivers (Neo4j, Memgraph, Kuzu, Apache AGE, Neptune); the graph_store config block is no longer read, and search results no longer carry a relations field. On the managed Platform there is no graph store to configure and no graph payload in the response — entity connections reach the caller only through the combined score. Rows reflect each product's public docs and source as of August 2026.

m0Reach for Mem0 when

You are giving a single assistant persistent memory, want a mature SDK with broad framework integrations, and one identity scope — user, agent, run, or app — describes how your data partitions.

SReach for Statewave when

Agents run in production across many sessions and you need deterministic context, provenance back to source episodes, policy enforced on the read path, and an auditable receipt for every decision.

One returning customer, two runtimes

A support agent resumes a customer thread three weeks later. In between, the customer moved house and pasted a card number into an earlier message. The same episode history runs through each system.

m0Mem0 · search by id
# retrieve context for the reply
› client.search("where do I ship it",
  user_id="cust_5521")
# ranked by relevance
old address · Elm Ststale, no expiry set
card 4242 4242 ····pii, no policy gate
Expiry, redaction and any policy on the read path are left to the application to build and keep correct.
SStatewave · assemble + govern
# assemble a ranked, bounded bundle
› get_context(subject="cust_5521",
  task="where do I ship it", max_tokens=1500)
new address · Oak Avevalid +3 · ranked #1
old address · Elm St−4 expired · dropped
card ●●●● ●●●● ····label:pii · redacted
The runtime decides: the superseded address scores out, the card is redacted by its policy label, and the receipt stores an integrity hash of exactly what was delivered.

Every call leaves a receipt

Mem0 leaves auditability to your application. In Statewave every assembly is governed and recorded in the core, on the read path, under Apache 2.0.

state-assembly receiptimmutable · ULID-addressable
receipt_id01J9Z4RT8K···
integrity_hashsha256:a3f9c1e0···
policy_bundlebundle:7c21 (enforce)
included · 3 facts, 2 episodes · 1,180/1,500 tokens
profile_factconf 0.92 · valid[ep_4, ep_9]
procedureconf 0.88 · valid[ep_2]
episode_summarysupersededdropped
1 memory redacted · label:pii
{}
Policy engine
Content-hashed YAML or JSON bundles. Deny or redact by sensitivity label and caller identity; log_only records each decision so you can audit a policy before enforcing it.
#
Sensitivity labels
Per-memory pii, financial, and secret tags in a GIN-indexed array, so policy filters run inside the query rather than after it.
←
Full provenance
Every compiled memory keeps the source episode ids, confidence score, and validity window it was derived from.
⌫
Subject deletion
One GDPR-style call erases every episode, memory, and receipt for a subject, leaving no orphaned rows behind.

A fair, in-harness run

Measured on Mem0's own harness, same models, judge unchanged. A narrow margin you can re-run beats an inflated one you cannot.

LoCoMo · LLM-judgen=1,540
SStatewave0.905
m0mem0 cloud0.899
m0mem0 OSS0.866
Note · mem0 OSS caps retrieval at ≤20 memories/query by library default; Statewave and cloud honor the top-200 request.
LongMemEvaln=30 · directional
0.933
mem0 cloud
·
0.833
mem0 OSS

Statewave scored higher on both in this run. Treat n=30 as directional; LoCoMo at n=1,540 is the robust figure.

8support eval criteria, open harness

Facts persist across sessions, token budgets hold, provenance traces to source episodes, and compilation stays idempotent.

reproduce it yourself · statewave-memory-benchmarks
$ git clone https://github.com/smaramwbc/statewave-memory-benchmarks.git
$ cd statewave-memory-benchmarks && pip install -r requirements.txt
$ python -m benchmarks.locomo.run --backend statewave \
  --answerer-model gpt-4o --judge-model gpt-4o
# same gpt-4.1 extraction, judge & scoring code untouched from upstream

Moving over from Mem0

One command boots the whole runtime. Every Mem0 call has a direct counterpart, and each write lands as an immutable episode.

one command · auto-wires Claude Code, Cursor, Codex
$ npx @statewavedev/statewave
→ API + admin console + Postgres up via Docker · healthy in under 2 min · no account
MEM0 SDK
STATEWAVE
client.add("…", user_id="cust_5521")
create_episode(subject="cust_5521", event="…")
Ingested as an immutable episode; compilers extract typed memories.
client.search("…", user_id="cust_5521")
get_context(subject="cust_5521", task="…", max_tokens=1500)
Ranked, token-bounded bundle plus a receipt of what was delivered.
client.get_all(user_id="cust_5521")
memories(subject="cust_5521", kind="profile_fact")
Browse by kind, subject, or validity; provenance attached.
client.delete_all(user_id="cust_5521")
delete_subject("cust_5521")
Removes every episode, memory, and receipt in one call — receipts included.

Frequently asked

How is Statewave different from Mem0?

Mem0 ranks memories by relevance for an id you pass. Statewave compiles raw episodes into typed memories, ranks them with a fixed scoring model to a token budget, applies policy on the read path, and returns an integrity-hashed receipt of exactly what was delivered.

What makes retrieval deterministic?

A fixed scoring model: kind priority (3–10), recency (0–5), task relevance (0–8), and temporal validity (−4 to +3). The same subject, task, and budget produce the same bundle every time.

What is a state-assembly receipt?

An immutable, ULID-addressable record of one context call. It carries a byte-level integrity hash of what was delivered and references the policy bundle hash, so ‘what did the agent see, under which policy’ is answerable forever.

Does it work with Claude, Cursor, or Codex?

Yes. One command (npx @statewavedev/statewave) boots the runtime and auto-wires Claude Code, Claude Desktop, Cursor, VS Code Copilot, and Codex CLI. Any MCP-compatible client connects too.

Can I run it fully offline?

Yes. Storage is Postgres-only and self-hosted. The heuristic compiler keeps everything on your network; nothing leaves unless you configure an LLM compiler or hosted embeddings.

Give your agent context it can prove

Self-host the Apache 2.0 runtime, wire it to your MCP client, and every context call comes back with a receipt.

"mem0" is a trademark of its respective owner. References to mem0 on this page are nominative, for benchmark-comparison purposes only, and do not imply any affiliation with or endorsement by mem0ai.