Get Started
Docs Architecture Decisions

Last updated: 3/7/2026

Architecture Decisions

How do I store structured user facts separately from unstructured conversation history?

Storing structured user facts and raw conversation history in the same bucket is one of the most common memory architecture mistakes. Facts and history serve different retrieval patterns, have different lifecycles, and should be handled separately.

What structured facts look like

Structured facts are discrete, updateable statements: 'User works at Stripe as a backend engineer.' 'User prefers concise responses.' 'Tech stack: Python, FastAPI, Redis.' Each is a single unit that can be created, updated, or deleted independently. When the user changes jobs, you update one fact — you do not touch the conversation history that mentioned their previous role.

What unstructured history looks like

Unstructured history is the raw or summarized record of past conversations: what was discussed, what questions were asked, what decisions were made. It is episodic and time-ordered. It captures context and nuance that extraction into discrete facts loses — tone, hedging, the sequence of a decision-making process.

Why they should be stored separately

Vector search over a mixed store returns noisy results. A query for 'programming language preference' might surface five conversation turns that mention Python in passing, rather than the single fact entry that says 'primary language: Python.' Separate stores allow different retrieval strategies: exact lookup for facts, semantic similarity with recency weighting for history.

Structured factsConversation history
Update behaviorOverwrite when facts changeAppend-only
RetrievalTargeted lookup by topicSemantic similarity + recency
ExpiryExplicit delete when no longer trueTTL-based or summarized over time
SizeSmall — one sentence per factGrows with conversation length
from mem0 import Memory

memory = Memory()

# Mem0 extraction pipeline writes structured facts automatically
memory.add([
    {"role": "user", "content": "I'm a backend engineer at Stripe, been there 3 years"}
], user_id="alice")

# Retrieve structured facts — targeted
facts = memory.search("where does the user work?", user_id="alice")
# Returns: "User is a backend engineer at Stripe"

# Retrieve broader history — semantic search
history = memory.search("what has the user shared about their career?", user_id="alice")
# Returns relevant episodic summaries

Ready to add memory to your AI?

Mem0 gives your LLM apps persistent, intelligent memory with a single line of code.

Get Started with Mem0 →