Open-source AI memory database for long-lived agents.
Persistent memory, hybrid retrieval, graph context, shared knowledge, and controlled forgetting in one Rust-native stack.
Documentation ย โขย Website ย โขย Issues ย โขย Discord
"The rose of old remains only in its name; we hold only the naked name."
โ Bernard of Cluny
Inspired by The Name of the Rose, Memorose is building a distributed, multimodal long-term memory lake โ reliable, continuously evolving, and highly flexible memory infrastructure.
Memorose is not a vector wrapper. It is a self-hosted memory runtime for agents: ingest events, consolidate durable memory, retrieve with hybrid search, project shared knowledge, and control memory lifecycle.
Most agent memory systems are still vector stores with nicer branding. Real agents need a memory runtime that can remember facts and procedures, retrieve through more than one signal, and enforce boundaries across agent, user, and organization scopes.
Memorose is a self-hosted Rust system built for that exact job:
- Layered Memory: From raw events to stable memory, insights, and goals.
- Factual + Procedural: Stores both what happened and how work gets done.
- Domain-Aware: Strict isolation across agent, user, and organization scopes.
- Hybrid Retrieval: Vectors, text search, graph expansion, and reranking combined.
- Memory Lifecycle: Denoising, compression, linking, reflection, semantic update, and optional forgetting.
- Multimodal Native: Text, image, audio, and video enter the same memory system.
- Rust-Native Stack: Embedded storage with no Python dependency chains.
Self-hosted. Rust-native. Designed for agents that need durable memory instead of another prompt appendix.
Raw events become stable memory, insights, and goals through a clear L0-L3 pipeline.
Memory is isolated across agent, user, and organization scopes before it is shared upward.
Store both what happened (facts) and how work gets done (procedures).
Vectors, full-text, graph expansion, and reranking work together in one unified stack.
Denoise, compress, align, associate, reflect, semantic update, and optional forgetting are part of the runtime.
Text, image, audio, and video can enter and be searched within the same memory system.
Start with Docker, or build from source if you want the full local stack.
docker run -d \
--name memorose \
-p 3000:3000 \
-p 3100:3100 \
-v memorose_data:/app/data \
-e GOOGLE_API_KEY="your_google_api_key_here" \
-e MEMOROSE__LLM__MODEL="gemini-3.1-flash-lite-preview" \
-e MEMOROSE__LLM__EMBEDDING_MODEL="gemini-embedding-2-preview" \
-e DASHBOARD_ADMIN_PASSWORD="your_secure_password" \
dylan2024/memorose:latestOr build from source
Requirements:
- Rust 1.91+
protobuf-compilercmakelibclang
On Debian/Ubuntu:
sudo apt-get update
sudo apt-get install -y protobuf-compiler cmake libclang-devgit clone https://github.com/ai-akashic/Memorose.git
cd Memorose
export RUST_MIN_STACK=8388608
cargo build --release -p memorose-server
export GOOGLE_API_KEY="your_google_api_key_here"
./target/release/memorose-serverSend one interaction, observation, or tool result into the memory runtime.
export STREAM=$(uuidgen)
curl -s -X POST http://localhost:3000/v1/users/dylan/streams/$STREAM/events \
-H "Content-Type: application/json" \
-d '{"content": "I prefer Rust over Python. I hate unnecessary meetings. My dog is named Rosie."}'Ask a new query and let the agent recall stable memory, not just the latest context window.
curl -s -X POST http://localhost:3000/v1/users/dylan/streams/$STREAM/retrieve \
-H "Content-Type: application/json" \
-d '{"query": "What should I keep in mind when working with Dylan?"}'Cross-modal query example
curl -s -X POST http://localhost:3000/v1/users/dylan/streams/$STREAM/retrieve \
-H "Content-Type: application/json" \
-d '{"query": "what is this?", "image": "'$(base64 -i photo.jpg)'"}'Response:
{
"results": [
["Dylan prefers Rust, dislikes unnecessary meetings, has a dog named Rosie", 0.94]
]
}If your SDK or agent runtime wants deterministic prompt control, call the sidecar endpoint first and prepend the returned context yourself.
curl -s -X POST http://localhost:3000/v1/memory/context \
-H "Content-Type: application/json" \
-d '{
"user_id": "dylan",
"query": "What should I keep in mind before helping Dylan?",
"token_budget": 240,
"limit": 8,
"format": "text"
}'Response shape:
{
"query": "What should I keep in mind before helping Dylan?",
"format": "text",
"strategy": "adaptive_compact",
"token_budget": 240,
"used_token_estimate": 126,
"matched_count": 5,
"included_count": 3,
"truncated": false,
"context": "- [L1 factual user] Dylan prefers Rust over Python\n- [L1 factual user] Dylan hates unnecessary meetings",
"hits": [
{
"id": "7c9d6d54-45e8-4a89-9080-d4f50c2e0fe8",
"level": 1,
"memory_type": "factual",
"domain": "user",
"score": 0.94
}
]
}The Docker image runs the API server on 3000 and the dashboard on 3100.
| Setting | Purpose | Default / note |
|---|---|---|
MEMOROSE__LLM__PROVIDER |
LLM provider | Defaults to gemini; set to openai for OpenAI |
GOOGLE_API_KEY |
Gemini LLM and embedding provider | Required when provider is gemini |
OPENAI_API_KEY |
OpenAI provider key | Requires MEMOROSE__LLM__PROVIDER=openai |
MEMOROSE__LLM__MODEL |
Chat / reasoning model | Example: gemini-3.1-flash-lite-preview |
MEMOROSE__LLM__EMBEDDING_MODEL |
Embedding model | Example: gemini-embedding-2-preview |
DASHBOARD_ADMIN_PASSWORD |
Dashboard admin password | Defaults to admin if unset; set this in real deployments |
MEMOROSE__FORGETTING__ENABLED |
Background forgetting worker | Disabled by default |
MEMOROSE__VECTOR__MAX_INDEX_SIZE_GB |
LanceDB index size guardrail | Defaults to 5 |
Forgetting is available through preview / execute flows and can be enabled for background pruning, but it is intentionally disabled by default.
Memorose processes memories through a 4-tier cognitive pipeline, modeled after human memory consolidation:
Event (text/image/audio/video/json)
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ L0 Working Memory โ
โ Raw event log. Append-only. Zero processing. โ
โ โบ RocksDB โ
โโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Background workers (async)
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ L1 Episodic Memory โ
โ Compressed summaries. Vectorized. Auto-linked. โ
โ โบ RocksDB + LanceDB + Tantivy โ
โ โ
โ Operations: Compress โโบ Embed โโบ Associate โ
โโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Community detection + LLM synthesis
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ L2 Semantic Memory โ
โ Abstract knowledge clusters. Cross-session insight.โ
โ โบ Knowledge Graph โ
โ โ
โ Operations: Insight โโบ Reflect โ
โโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Goal / task decomposition
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ L3 Goals & Task Memory โ
โ Goal structures, task trees, progress, outcomes. โ
โ โบ RocksDB โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Optional forgetting can run across memory tiers when enabled:
importance decay + threshold pruning + deduplication
View Mermaid Diagram
flowchart TD
subgraph Input["Input / ่พๅ
ฅ"]
I["Events / ไบไปถ<br/>text ยท image ยท audio ยท video ยท json"]
end
subgraph Layers["L0-L3 Layered Memory / ๅๅฑ่ฎฐๅฟ"]
L0["L0 Raw Events / ๅๅงไบไปถ<br/>append-only event log"]
L1["L1 Stable Memory / ็จณๅฎ่ฎฐๅฟ<br/>facts + procedures"]
L2["L2 Insights / ๆดๅฏๅฑ<br/>topics + clusters + reflections"]
L3["L3 Goals & Task Memory / ็ฎๆ ไธไปปๅก่ฎฐๅฟ<br/>goals + task trees + dependencies"]
end
subgraph Evolution["Memory Lifecycle / ่ฎฐๅฟ็ๅฝๅจๆ"]
E1["Denoise / ้ๅช"]
E2["Compress / ๅ็ผฉ"]
E3["Align / ๅฏน้ฝ"]
E4["Associate / ๅ
ณ่"]
E5["Reflect / ๅๆ"]
E6["Forget / ้ๅฟ<br/>optional decay + prune on L1-L3"]
end
subgraph Domains["Memory Domains / ่ฎฐๅฟ้ขๅ"]
D1["Agent / Agent"]
D2["User / ็จๆท"]
D3["Organization / ็ป็ป"]
end
I --> L0
L0 --> E1 --> E2 --> L1
L1 --> E3 --> E4 --> L1
L1 --> E5 --> L2
L2 --> L3
L1 -. local native memory / ๆฌๅฐๅ็่ฎฐๅฟ .-> D1
L1 -. local native memory / ๆฌๅฐๅ็่ฎฐๅฟ .-> D2
L2 -. projected organizational memory / ็ป็ปๅ
ฑไบซ่ฎฐๅฟ .-> D3
E6 -. affects memory units only / ไฝ็จไบ่ฎฐๅฟๅๅ
ๅฑ .-> L1
E6 -. affects memory units only / ไฝ็จไบ่ฎฐๅฟๅๅ
ๅฑ .-> L2
E6 -. affects memory units only / ไฝ็จไบ่ฎฐๅฟๅๅ
ๅฑ .-> L3
Every memory is indexed across three core dimensions:
Organization (org_id) โ Shared organizational boundary
โโ User (user_id) โ Factual: preferences, facts, profile
โโ Agent (agent_id) โ Procedural: tool usage, strategies, reflections
| Dimension | What it captures | Example |
|---|---|---|
| Organization | Shared boundary for reusable organizational knowledge | org: acme-corp |
| User | Facts, preferences, personal context | "Dylan prefers Rust and hates meetings" |
| Agent | Execution trajectories, learned strategies, tool patterns | "API X fails on large payloads โ use streaming instead" |
Memorose separates cognitive tier from memory domain:
- L0-L3 describes how memory is processed over time
- Agent / User / Organization describes who a memory belongs to and who it should serve
| Domain | Primary question | Typical content | Default sharing boundary |
|---|---|---|---|
| Agent Memory | How does this agent do the work? | Tool usage patterns, execution traces, recovery strategies | Private to one agent_id unless projected upward |
| User Memory | Who is this user and what do they want? | Preferences, identity, goals, constraints, personal context | Shared across agents serving the same user_id |
| Organization Memory | What knowledge is reusable across the org? | Policies, terminology, shared workflows, generalized practices | Shared within one org_id, subject to user opt-in |
These operations form the memory lifecycle pipeline:
- Align: Map multimodal input (text, image, audio, video) to structured events.
- Compress: LLM-extract high-density facts from verbose conversations (L0 โ L1).
- Associate: Auto-link semantically similar memories via cosine similarity.
- Insight: Community detection (Louvain/LPA) + LLM synthesis of abstract knowledge.
- Reflect: Per-session retrospective: what happened, what was learned.
- Update / Forget: Preview semantic updates or forgetting plans, then execute them deliberately. Background forgetting is disabled by default.
| Feature | Memorose | Mem0 | Zep | ChromaDB |
|---|---|---|---|---|
| Open Source | Yes | Partial | Yes | Yes |
| Self-Hosted | Yes | No | Yes | Yes |
| Hybrid Search (Vector + BM25) | Yes | No | Yes | No |
| Knowledge Graph | Yes | Yes | No | No |
| Native Multimodal Embedding | Yes | No | No | No |
| Controlled Forgetting | Preview / execute; background off by default | No | No | No |
| Raft Replication | Yes | No | No | No |
| Built-in Dashboard | Yes | Yes | No | No |
| Language | Rust | Python | Go | Python |
Current performance work focuses on practical startup behavior, bounded vector index growth, hybrid retrieval latency, and reproducible benchmark coverage.
- Retrieval target: low-latency hybrid search for agent recall paths.
- Storage guardrails: LanceDB index size limits and degraded startup behavior are configurable.
- Benchmark direction: publish reproducible workloads before treating numbers as release claims.
See examples/README.md for local benchmark scripts and examples.
Memorose includes a Next.js dashboard for observing memory, graph context, cluster state, and correction workflows.
Recommended local startup:
./scripts/start_cluster.sh start --clean --buildFeatures:
- Memory Browser: Search, filter by organization/user/agent, inspect memories.
- Knowledge Graph: Interactive visualization of memory relationships.
- Playground: Live query testing with real-time results and multi-modal chat.
- Cluster Health: Multi-node Raft status monitoring.
- Correction Observability: Inspect RAC decisions, review queues, and semantic forget/update previews.
Natural-language forget / update flows and sidecar context injection are designed to be called from your SDK or agent runtime, while the dashboard acts as the observability and review surface.
from examples.python.http_client import MemoroseClient
client = MemoroseClient(
base_url="http://localhost:3000",
user_id="dylan",
stream_id="chat-session",
)
context = client.build_context(
"What should I keep in mind before helping Dylan?",
token_budget=240,
)
prompt = f"""You are a helpful assistant.
Relevant memory:
{context["context"]}
User: Help Dylan plan the next sprint."""curl -X POST http://localhost:3000/v1/users/dylan/memories/semantic/preview \
-H "Content-Type: application/json" \
-d '{
"instruction": "I now live in Beijing and no longer live in Shanghai",
"mode": "auto"
}'| Method | Endpoint | Description |
|---|---|---|
POST |
/v1/users/:uid/streams/:sid/events |
Ingest event (text, image, audio, video, json) |
POST |
/v1/users/:uid/streams/:sid/retrieve |
Hybrid search with optional cross-modal query |
POST |
/v1/memory/context |
Return prompt-ready condensed context for SDK sidecar injection |
POST |
/v1/users/:uid/memories/semantic/preview |
Preview semantic forget/update plan |
POST |
/v1/users/:uid/memories/semantic/execute |
Execute semantic forget/update plan |
GET |
/v1/dashboard/corrections/reviews |
Observe pending / approved / rejected correction reviews (dashboard auth) |
GET |
/v1/users/:uid/tasks/tree |
Get all goal/task hierarchies |
GET |
/v1/users/:uid/tasks/ready |
Get auto-executable tasks |
PUT |
/v1/users/:uid/tasks/:tid/status |
Update task status |
POST |
/v1/users/:uid/graph/edges |
Add graph edge |
GET |
/v1/status/pending |
Pending event count |
Use /v1/memory/context when you want Memorose to do retrieval + compression, but keep final prompt assembly in your own orchestrator.
- Gateway pattern: call
/retrievedirectly from your application and consume ranked memory hits. - Sidecar pattern: call
/v1/memory/context, receive a pre-compressedcontextblock, then prepend it to your LLM prompt. - Budget control: set
token_budgetin the JSON body or s 67ED endX-Memory-Budget. - Adaptive compression: large budgets prefer detailed L1 memory; tiny budgets prioritize denser L2/L3 summaries.
- Output formats:
format: "text"orformat: "xml".
- Python & TypeScript SDKs
- Streaming event ingestion (WebSocket / SSE)
- Helm chart for Kubernetes deployment
- Plugin system for custom memory processors
We welcome contributions of all kinds.
# Fork, clone, then:
cargo test -p memorose-core
cargo run -p memorose-serverSee CONTRIBUTING.md for guidelines.