# Deep Dive: Letta (MemGPT) vs Chroma vs sqlite-vec for iEvo Agent Memory

**Date**: 2026-03-04
**Researcher**: Researcher Agent
**Context**: iEvo is a Python CLI tool that orchestrates AI agents using Docker containers, needs persistent semantic memory across sessions.

---

## Table of Contents

1. [Letta (MemGPT) Deep Dive](#1-letta-memgpt-deep-dive)
2. [Chroma Deep Dive](#2-chroma-deep-dive)
3. [sqlite-vec Deep Dive](#3-sqlite-vec-deep-dive)
4. [Detailed Comparison Table](#4-detailed-comparison-table)
5. [Recommendation for iEvo](#5-recommendation-for-ievo)

---

## 1. Letta (MemGPT) Deep Dive

### What Is It

Letta (formerly MemGPT) is a platform for building **stateful agents** with persistent memory. It implements the "LLM as Operating System" paradigm from the MemGPT paper (arXiv:2310.08560), where the LLM manages its own context window like an OS manages virtual memory -- paging information in and out of a limited context window using tool calls.

- **GitHub**: https://github.com/letta-ai/letta -- 21.4k stars, 2.2k forks, 158 contributors
- **License**: Apache-2.0
- **Latest release**: v0.16.6 (March 4, 2026) -- actively maintained
- **Python**: >=3.11, <3.14

### Architecture: Three-Tier Memory

Letta provides three memory tiers that work together:

#### 1. In-Context Memory (Core Memory / Memory Blocks)

Structured sections of the agent's context window that persist across all interactions. They are always visible -- no retrieval needed. Think of them as an editable system prompt.

- Defined by labeled blocks: `human` (user info), `persona` (agent personality), plus custom blocks
- Each block has: label, description, value, character limit (default ~2k chars)
- The agent can **self-edit** blocks via built-in tools:
  - `core_memory_append(name, content)` -- add text to a block
  - `core_memory_replace(name, old_content, new_content)` -- edit block text
- Blocks can be **shared** across multiple agents (shared memory)
- Blocks can be marked `read_only: true` to prevent agent modification
- Rendered as `<memory_blocks>` XML in the prompt with current/max character counts

#### 2. Archival Memory (Long-Term Vector Store)

A semantically searchable database for facts, knowledge, and information that does not fit in the context window. Unlimited storage capacity.

- Agent inserts via `archival_memory_insert(content, tags=[...])`
- Agent searches via `archival_memory_search(query, tags=[], page=0)`
- Semantic search: understands concepts and meaning, not just keywords
- Supports hybrid search: semantic (vector) + keyword (full-text), ranked by Reciprocal Rank Fusion (RRF)
- Developer API: `client.agents.passages.insert()` / `client.agents.passages.search()`
- Tag-based filtering for organized retrieval
- Storage backend:
  - PostgreSQL mode: pgvector extension for vector search
  - SQLite mode: **sqlite-vec** extension for vector search (yes, Letta uses sqlite-vec internally)

#### 3. Recall Memory (Conversation History)

Automatic logging of all conversational history with date search and text search tools.

- All messages, reasoning, tool calls persisted in database
- Retrievable even after context compaction
- Agent has date search and text search tools for history

### Context Window Management (Compaction)

When conversation history grows too long, Letta automatically **compacts** (summarizes) older messages:

- Sliding window mode: keeps ~70% most recent history
- Summarization via LLM call (adds cost)
- Evicted messages are NOT lost -- still retrievable via API and recall tools
- Configurable: `sliding_window_percentage` parameter

### Docker Compose Setup

Letta's compose.yaml defines **three services**:

```yaml
services:
  letta_db:         # PostgreSQL with pgvector
    image: ankane/pgvector:v0.5.1
    ports: [5432]
    volumes: [./.persist/pgdata:/var/lib/postgresql/data]
    healthcheck: pg_isready -U letta

  letta_server:     # Main application
    image: letta/letta:latest
    ports: [8083, 8283]
    depends_on: letta_db (service_healthy)
    env: OPENAI_API_KEY, ANTHROPIC_API_KEY, OLLAMA_BASE_URL, etc.

  letta_nginx:      # Reverse proxy (optional)
    image: nginx:stable-alpine3.17-slim
    ports: [80]
```

Port 8283 is the primary API endpoint (`http://localhost:8283/v1`).

### Can It Work Without PostgreSQL? (SQLite Mode)

**YES.** Two approaches:

1. **pip install** (defaults to SQLite):
   ```bash
   pip install letta[sqlite]
   letta server
   ```
   - Database at `~/.letta/letta.db`
   - Uses **sqlite-vec** extension internally for vector search
   - No PostgreSQL needed at all
   - **Caveat**: database migrations between Letta versions are NOT officially supported with SQLite. Only PostgreSQL gets migration support.

2. **Docker** (defaults to PostgreSQL):
   - The Docker image includes embedded PostgreSQL
   - Can use external PostgreSQL via `LETTA_PG_URI` env var

### Python SDK

Two packages:

| Package | Size | Purpose |
|---------|------|---------|
| `letta` (1.5 MB wheel, 8.2 MB source) | Server + CLI + all functionality | Running your own Letta server |
| `letta-client` (390 KB wheel) | SDK client only | Connecting to a running Letta server |

**Client SDK usage:**
```python
from letta_client import Letta

client = Letta(api_key=os.getenv("LETTA_API_KEY"))
# Or connect to local server:
# client = Letta(base_url="http://localhost:8283")

agent = client.agents.create(
    model="anthropic/claude-sonnet-4-20250514",
    embedding="openai/text-embedding-3-small",
    memory_blocks=[
        {"label": "human", "value": "User info", "limit": 5000},
        {"label": "persona", "value": "Agent info", "limit": 5000},
    ],
    tools=["web_search", "fetch_webpage"]
)

response = client.agents.messages.create(
    agent_id=agent.id,
    input="What do you know about me?"
)
```

### Supported LLM Providers

- OpenAI (recommended: GPT-5.2)
- Anthropic (Claude, via ANTHROPIC_API_KEY)
- Ollama (local models, via OLLAMA_BASE_URL)
- vLLM, OpenLLM
- Groq
- Azure OpenAI
- Google Gemini

**Embedding models**: Uses OpenAI text-embedding-3-small by default. Anthropic does NOT provide embedding models, so a separate embedding provider is always needed. Free option: `letta-free` embeddings endpoint.

### Additional SDKs (Experimental)

Letta offers two additional experimental SDKs:

1. **learning-sdk** (41 stars, Apache-2.0): Drop-in wrapper that adds continual learning to any LLM call. Wraps OpenAI/Anthropic/Gemini calls in a `learning()` context. **Requires a running Letta server.**

2. **ai-memory-sdk** (40 stars, Apache-2.0): Lightweight memory layer using "subconscious agent" pattern. Creates background Letta agents that asynchronously process messages and update memory blocks. **Requires a running Letta server.**

### Performance Considerations

- Letta server is a **separate process** (REST API on port 8283)
- Every memory operation involves an LLM call (agent decides what to memorize)
- Auto-compaction involves additional LLM calls for summarization
- Benchmark: 74.0% on LoCoMo (memory QA benchmark) vs Mem0's 68.5%
- Agent loop overhead: the agent must decide on every turn whether to save to memory, search archival, send message, etc.
- Sleep-time agents (v1): memory management handled asynchronously, improving response times

### Key Insight: What Letta Provides That sqlite-vec Does Not

| Capability | Letta | sqlite-vec (raw) |
|-----------|-------|-----------------|
| Vector search | Yes (uses sqlite-vec or pgvector internally) | Yes |
| In-context memory (editable system prompt) | Yes -- agent self-manages | No -- you build this yourself |
| Auto-compaction/summarization | Yes -- automatic context window management | No -- you build this yourself |
| Conversation history with search | Yes -- recall memory tier | No -- you build this yourself |
| Agent decides what to remember | Yes -- autonomous memory management | No -- you decide programmatically |
| Shared memory across agents | Yes -- memory blocks can be shared | No -- you build this yourself |
| Multi-session persistence | Yes -- all state in DB | Partial -- you manage schema |
| Embedding generation | Yes -- built-in via provider | No -- you bring sentence-transformers |

**Bottom line**: Letta is a **complete agent memory operating system**. sqlite-vec is a **vector search primitive**. Letta actually uses sqlite-vec inside its SQLite mode.

---

## 2. Chroma Deep Dive

### What Is It

Chroma is an open-source embedding database purpose-built for AI applications. It provides vector search with metadata filtering, built-in embedding functions, and both embedded and client-server deployment modes.

- **GitHub**: https://github.com/chroma-core/chroma -- 26.4k stars
- **License**: Apache-2.0
- **Latest release**: 1.5.2 (February 27, 2026)
- **Python**: >=3.9
- **Package size**: 20-22 MB (wheel, varies by platform)

### Embedded Mode vs Server Mode

#### Embedded Mode (PersistentClient) -- No Server Process

```python
import chromadb

# Runs entirely in-process, no server needed
client = chromadb.PersistentClient(path="./chroma_db")

collection = client.create_collection(name="agent_memories")

# Add documents with metadata
collection.add(
    documents=["Docker isolation improves security", "PTY bridges need pexpect"],
    metadatas=[{"agent": "architect", "session": "003"}, {"agent": "coder", "session": "005"}],
    ids=["mem1", "mem2"]
)

# Semantic search with metadata filtering
results = collection.query(
    query_texts=["How do we isolate agent execution?"],
    n_results=5,
    where={"agent": "architect"}  # metadata filter
)
```

- Runs in the same Python process -- no separate server
- Stores data locally on disk at the specified path
- Single-threaded (file-level locks from underlying SQLite)
- Default embedding: **all-MiniLM-L6-v2** via sentence-transformers (same model recommended for sqlite-vec)
- Automatic embedding: pass documents as strings, Chroma embeds them automatically

#### Server Mode (HttpClient)

```bash
chroma run --path /chroma_db_path
```
```python
client = chromadb.HttpClient(host="localhost", port=8000)
```

- Separate process with FastAPI backend
- Multi-process access via HTTP/REST API
- Docker deployment available

### Storage Architecture

Chroma's storage pipeline:

1. **Incoming embeddings** -> brute force buffer (fast ingest)
2. **Buffer full** -> transfer to HNSW index (approximate nearest neighbor)
3. **Persist** -> Apache Arrow format on disk

Storage components:
- **Metadata**: DuckDB / SQLite for small deployments
- **Vectors**: Parquet files (columnar, compressed)
- **Index**: HNSW (Hierarchical Navigable Small World) for ANN search

### Metadata Filtering

Chroma supports filtering alongside vector search:

```python
# WHERE clause on metadata
results = collection.query(
    query_texts=["memory question"],
    where={"agent": "spec-writer"},
    where_document={"$contains": "requirement"}
)
```

Supports: `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$in`, `$nin`, `$and`, `$or`, `$contains`, `$not_contains`.

### Python API Ergonomics

- `collection.add()` -- add documents (auto-embeds)
- `collection.query()` -- semantic search
- `collection.update()` -- update documents
- `collection.delete()` -- delete by ID or filter
- `collection.get()` -- retrieve by ID or metadata filter
- `collection.count()` -- count documents
- `collection.peek()` -- preview first N documents

No need to manage embeddings manually unless you want custom embedding functions.

### Key Differences from sqlite-vec

| Feature | Chroma | sqlite-vec |
|---------|--------|-----------|
| Search algorithm | HNSW (ANN, fast at scale) | Brute-force KNN (exact, slower at scale) |
| Package size | 20-22 MB + onnxruntime (~200 MB) | 100-280 KB |
| Built-in embeddings | Yes (all-MiniLM-L6-v2 default) | No (bring your own) |
| Metadata filtering | Rich (WHERE clauses) | Manual (SQL WHERE on separate columns) |
| Auto-embedding | Yes (pass strings) | No (pass vectors) |
| Concurrency | Poor (SQLite file locks) | Same (SQLite file locks) |
| Storage format | Arrow/Parquet + HNSW | SQLite virtual table |
| Dependencies | Heavy (onnxruntime, grpcio, kubernetes, numpy, etc.) | Zero dependencies |

### Concerns for iEvo

1. **Heavy dependencies**: chromadb pulls in onnxruntime (~200 MB), grpcio, kubernetes client, numpy, tokenizers, opentelemetry, posthog telemetry. Total install weight: ~300+ MB.
2. **onnxruntime compatibility**: Known issues on macOS ARM64, Python 3.13+ compatibility problems reported.
3. **Telemetry**: posthog analytics built in (can be disabled).
4. **Python 3.13 support**: chromadb requires Python >=3.9 but onnxruntime has had issues with Python 3.13.

---

## 3. sqlite-vec Deep Dive

### What Is It

sqlite-vec is a pure C SQLite extension that adds vector search (brute-force KNN) as a virtual table. Zero dependencies. Runs anywhere SQLite runs.

- **GitHub**: https://github.com/asg017/sqlite-vec -- 7.1k stars
- **License**: MIT / Apache-2.0 (dual)
- **Latest release**: 0.1.6 (November 2024)
- **Package size**: 100-280 KB (varies by platform)
- **Author**: Alex Garcia (Mozilla-backed)

### How It Works

```python
import sqlite3
import sqlite_vec

db = sqlite3.connect(".ievo/memory.db")
db.enable_load_extension(True)
sqlite_vec.load(db)

# Create vector table
db.execute("""
    CREATE VIRTUAL TABLE IF NOT EXISTS memories
    USING vec0(
        embedding float[384],
        +content TEXT,
        +agent TEXT,
        +session TEXT,
        +timestamp TEXT
    )
""")

# Insert (you generate embeddings externally)
db.execute(
    "INSERT INTO memories(embedding, content, agent, session, timestamp) VALUES (?, ?, ?, ?, ?)",
    [embedding_bytes, "Docker isolation pattern", "architect", "003", "2026-03-04"]
)

# KNN search
rows = db.execute("""
    SELECT content, agent, session, distance
    FROM memories
    WHERE embedding MATCH ?
    AND k = 5
    ORDER BY distance
""", [query_embedding_bytes]).fetchall()
```

### Performance at Scale

Benchmarks with 100k vectors:

| Dimension | Float (avg ms) | Bit (avg ms) |
|-----------|----------------|---------------|
| 3072 | 214 ms | 11 ms |
| 1536 | 105 ms | -- |
| 1024 | <75 ms | -- |
| 768 | <75 ms | -- |
| 384 | <75 ms | -- |
| 192 | <75 ms | -- |

For iEvo's use case (384-dim all-MiniLM-L6-v2, likely <10k memories per project), queries will be well under 10 ms.

### Limitations

1. **Brute-force only**: No ANN index (HNSW, IVF). At 100k+ vectors with high dimensions, gets slow. HNSW would be 8-80x faster.
2. **No built-in embeddings**: You must generate embeddings yourself (e.g., sentence-transformers).
3. **No metadata filtering in vector query**: Must combine with regular SQL (which is actually powerful but requires manual query composition).
4. **No auto-compaction/summarization**: Pure storage primitive.
5. **v0.1.6**: Still pre-1.0. API may change.

### Why It Is Still Compelling for iEvo

1. **100-280 KB** package vs 20+ MB (Chroma) or 1.5+ MB (Letta)
2. **Zero dependencies** -- no onnxruntime, no grpcio, no kubernetes client
3. **Same SQLite file** as everything else (REQ-012 trajectory data, manifest, etc.)
4. **Letta itself uses sqlite-vec** in its SQLite mode -- if the Letta team trusts it, it works
5. **SQL-native** -- powerful joins with other tables (trajectories, sessions, etc.)
6. **iEvo's scale**: <10k memories per project -- brute-force is perfectly fast

---

## 4. Detailed Comparison Table

| Dimension | Letta (MemGPT) | Chroma | sqlite-vec |
|-----------|----------------|--------|-----------|
| **Category** | Agent memory OS | Vector database | Vector search extension |
| **GitHub stars** | 21.4k | 26.4k | 7.1k |
| **License** | Apache-2.0 | Apache-2.0 | MIT / Apache-2.0 |
| **Package size** | 1.5 MB (client) / 8.2 MB (server) | 20-22 MB + ~200 MB deps | 100-280 KB |
| **Total install weight** | ~500 MB+ (with all deps) | ~300 MB+ (onnxruntime) | <1 MB (+ 80 MB if adding sentence-transformers) |
| **Python version** | >=3.11, <3.14 | >=3.9 | >=3.0 |
| **Search algorithm** | sqlite-vec (SQLite) or pgvector (PG) | HNSW (ANN) | Brute-force KNN |
| **Deployment** | Client/server (REST API on :8283) | Embedded or client/server | Embedded (SQLite extension) |
| **Requires server process** | YES (letta server or Docker) | NO (PersistentClient) / YES (HttpClient) | NO |
| **Database** | SQLite or PostgreSQL | SQLite + DuckDB + Arrow | SQLite |
| **Built-in embeddings** | Yes (via LLM provider) | Yes (all-MiniLM-L6-v2 default) | No |
| **Metadata filtering** | Tags on archival passages | Rich WHERE clauses | SQL WHERE (manual) |
| **Auto-embedding** | Yes | Yes | No |
| | | | |
| **MEMORY FEATURES** | | | |
| **In-context memory** | YES -- editable system prompt blocks | No | No |
| **Archival memory (vector)** | YES -- semantic + keyword hybrid | YES -- HNSW + metadata | YES -- brute-force KNN |
| **Recall memory (history)** | YES -- conversation log with search | No | No |
| **Auto-summarization** | YES -- context compaction | No | No |
| **Agent self-manages memory** | YES -- agent decides what to save | No | No |
| **Shared memory across agents** | YES -- shared memory blocks | No (build yourself) | No (build yourself) |
| **Context window management** | YES -- sliding window + compaction | No | No |
| **Multi-session persistence** | YES -- all state in DB | YES -- persistent storage | YES -- SQLite file |
| | | | |
| **OPERATIONAL** | | | |
| **Setup complexity (no Docker)** | Medium: pip install + letta server | Low: pip install | Lowest: pip install |
| **Setup complexity (with Docker)** | Medium: docker run (PG bundled) | N/A (overkill for embedded) | N/A |
| **Offline operation** | Partial: needs LLM API for memory ops | YES (with local embeddings) | YES (with local embeddings) |
| **LLM cost overhead** | YES -- every memory op = LLM call | No | No |
| **Startup latency** | High: server boot + DB init | Low: file open | Lowest: SQLite open |
| **Concurrent access** | Yes (server handles it) | Poor (file locks) | Poor (file locks) |
| **Data portability** | DB dump / API export | Directory of files | Single .db file |
| | | | |
| **INTEGRATION** | | | |
| **Claude support** | Yes (ANTHROPIC_API_KEY) | N/A (embedding only) | N/A |
| **OpenAI support** | Yes | N/A | N/A |
| **Ollama support** | Yes (OLLAMA_BASE_URL) | N/A | N/A |
| **MCP integration** | Not built-in | Not built-in | Not built-in |
| **Fits iEvo's SQLite strategy** | No (separate DB or complex) | No (own storage format) | YES (same .db file) |

---

## 5. Recommendation for iEvo

### The Key Insight

The three tools serve **fundamentally different purposes**:

- **sqlite-vec** = storage primitive (vector search in SQLite)
- **Chroma** = vector database (storage + embeddings + metadata filtering)
- **Letta** = agent memory operating system (storage + embeddings + context management + auto-summarization + agent self-management)

They are not substitutes. They are layers of a stack. In fact, **Letta uses sqlite-vec internally** when running in SQLite mode.

### Challenging the Original Assessment

The original PROP-2026-03-04-memory-sqlite-vec.md dismissed Letta as "requires PostgreSQL, too heavy." This was partially wrong:

1. **Letta works with SQLite** via `pip install letta[sqlite]` + `letta server`. No PostgreSQL needed.
2. **Letta uses sqlite-vec internally** for vector search in SQLite mode.
3. **Docker is already in iEvo's stack** -- the `letta/letta:latest` container is not additional infrastructure complexity if iEvo already manages Docker containers.

However, the original assessment was right about one thing: **Letta requires a running server process** (REST API on port 8283). This is architecturally different from an embedded library call. For a CLI tool, this means:

- Either the CLI must start/manage a Letta server process (lifecycle management)
- Or a Letta Docker container must be running alongside agent sandboxes
- Every memory operation involves a network round-trip (localhost, but still)
- Every memory operation involves **an LLM call** (the Letta agent decides what to memorize) -- this adds latency AND cost

### Why Chroma Is NOT the Right Choice for iEvo

Despite 26.4k stars and a nice API, Chroma has problems for iEvo:

1. **Heavy dependencies**: onnxruntime (~200 MB), grpcio, kubernetes, posthog telemetry. Total ~300+ MB of dependencies for a CLI tool that should be lightweight.
2. **onnxruntime compatibility**: Known issues with Python 3.13+ and macOS ARM64. iEvo targets Python 3.13+.
3. **Separate storage**: Chroma uses its own storage format (Arrow/Parquet + HNSW files). This is a second data silo alongside SQLite (which iEvo uses for trajectories, config, etc.).
4. **No advantage over sqlite-vec at iEvo's scale**: With <10k memories per project, brute-force KNN on 384-dim vectors is <10ms. HNSW's advantage only shows at 100k+ vectors.
5. **Same concurrency limitations**: Both Chroma (embedded) and sqlite-vec use SQLite file-level locks.

**Chroma is the right choice for**: applications that need a standalone vector database with rich querying, don't care about dependency weight, and operate at 100k+ vector scale.

**Chroma is the wrong choice for**: a CLI tool that already uses SQLite, targets Python 3.13+, and has <10k vectors.

### Recommended Architecture for iEvo

#### Phase 1: sqlite-vec + sentence-transformers (Immediate, Low Effort)

Build iEvo's own memory layer on top of sqlite-vec. This is the right choice because:

1. **100-280 KB** package, zero dependencies
2. **Same SQLite database** as trajectory data (REQ-012)
3. **SQL-native**: powerful joins between memory, trajectories, sessions
4. **iEvo controls the memory logic**: what to save, when to search, how to rank
5. **Offline-first**: works without any API calls (local embeddings)
6. **No server process**: embedded in the CLI process
7. **Battle-tested**: Letta itself trusts sqlite-vec for its SQLite mode

**What to build:**
```
src/ievo/core/memory.py
  MemoryStore class:
    - SQLite + sqlite-vec + FTS5
    - save(content, metadata) -> embed locally + store
    - search(query, k=5) -> semantic KNN search
    - search_keyword(query) -> FTS5 full-text search
    - search_hybrid(query) -> combined ranking (RRF-style)
    - per-agent namespacing
    - session-aware metadata
```

**Embedding model**: sentence-transformers all-MiniLM-L6-v2 (384-dim, 80 MB, runs on CPU).

**Storage**: `.ievo/memory.db` -- single file, portable, same as trajectory DB or a separate DB file.

**Cost**: $0 per operation (local embeddings, local search).

#### Phase 2: Letta Integration for Advanced Memory (Medium Effort, Optional)

If/when iEvo needs agent-managed memory (agents deciding what to remember, auto-summarization, shared memory blocks), integrate Letta as an optional backend:

**Option A: Letta Docker sidecar** (recommended if Docker is already running)
- Add Letta to iEvo's Docker Compose alongside agent sandbox
- Agents connect to Letta via `letta-client` SDK (390 KB)
- Memory blocks for agent personas and user context
- Archival memory for long-term knowledge

**Option B: Letta pip + SQLite** (simpler but with caveats)
- `pip install letta[sqlite]` + start `letta server` as subprocess
- No PostgreSQL needed
- Caveat: no migration support between Letta versions

**When to trigger Phase 2:**
- When agents need to autonomously decide what to remember (not just programmatic save/search)
- When cross-agent shared memory becomes a real requirement (not speculative)
- When context window management / auto-summarization is needed for long sessions

#### Phase 3: Hybrid Architecture (sqlite-vec + Letta)

The two are not mutually exclusive:

- **sqlite-vec** handles: trajectory indexing, session search, structured memory (what iEvo's code controls)
- **Letta** handles: agent-autonomous memory, conversational context, persona management (what agents control)

This mirrors iEvo's architecture: the CLI orchestrates (sqlite-vec), agents reason (Letta).

### Summary Decision Matrix

| Criterion | sqlite-vec (Phase 1) | Letta (Phase 2) | Chroma |
|-----------|---------------------|-----------------|--------|
| Install weight | 280 KB | 390 KB client + server | 300+ MB |
| Server needed | No | Yes | No (embedded) |
| LLM cost per memory op | $0 | Yes (LLM call) | $0 |
| Offline | Yes | Partial | Yes |
| Agent self-management | No (code controls) | Yes (agent decides) | No |
| Context compaction | No (build yourself) | Yes (automatic) | No |
| Shared agent memory | No (build yourself) | Yes (built-in) | No |
| Fits iEvo SQLite stack | Perfect | Separate | No |
| Python 3.13+ safe | Yes | Yes (3.11-3.13) | Risk (onnxruntime) |
| Implementation effort | Low | Medium | Low |
| Right for Phase 1 | **YES** | Too heavy | No |
| Right for Phase 2+ | Keep as base | **YES (optional)** | No |

### Final Verdict

**Phase 1: sqlite-vec + sentence-transformers.** Build a clean MemoryStore abstraction. Zero infrastructure, zero API cost, single SQLite file, <10ms queries at iEvo's scale, same database as trajectories.

**Phase 2 (conditional): Letta as Docker sidecar.** Only when agents need autonomous memory management, auto-summarization, or shared memory blocks. Use `letta-client` SDK (390 KB) to connect to a Letta container that iEvo already manages via Docker. The sqlite-vec MemoryStore remains as the base layer for code-controlled memory (trajectories, structured observations).

**Never: Chroma.** Too heavy (300+ MB deps), Python 3.13+ risk, separate storage silo, no advantage at iEvo's scale.

---

## Sources

### Letta (MemGPT)
- [Letta GitHub](https://github.com/letta-ai/letta) -- 21.4k stars, Apache-2.0
- [Letta Docs: Intro to MemGPT](https://docs.letta.com/concepts/memgpt/)
- [Letta Docs: Memory Blocks](https://docs.letta.com/guides/agents/memory-blocks/)
- [Letta Docs: Archival Search](https://docs.letta.com/guides/agents/archival-search/)
- [Letta Docs: Context Engineering](https://docs.letta.com/guides/agents/context-engineering/)
- [Letta Docs: Compaction](https://docs.letta.com/guides/agents/compaction/)
- [Letta Docs: Docker Deployment](https://docs.letta.com/guides/selfhosting)
- [Letta Docs: Pip Installation](https://docs.letta.com/server/pip)
- [Letta Docs: Anthropic Provider](https://docs.letta.com/guides/server/providers/anthropic/)
- [Letta compose.yaml](https://github.com/letta-ai/letta/blob/main/compose.yaml)
- [Letta Blog: Benchmarking Agent Memory](https://www.letta.com/blog/benchmarking-ai-agent-memory) -- 74.0% LoCoMo
- [Letta Blog: V1 Agent Loop](https://www.letta.com/blog/letta-v1-agent)
- [Letta Blog: Agent Memory](https://www.letta.com/blog/agent-memory)
- [Letta Learning SDK](https://github.com/letta-ai/learning-sdk) -- 41 stars, Apache-2.0
- [Letta AI Memory SDK](https://github.com/letta-ai/ai-memory-sdk) -- 40 stars, Apache-2.0
- [Letta on PyPI](https://pypi.org/project/letta/) -- v0.16.6
- [letta-client on PyPI](https://pypi.org/project/letta-client/) -- v1.7.11
- [Letta on Docker Hub](https://hub.docker.com/r/letta/letta)
- [AWS: Letta with Aurora PostgreSQL](https://aws.amazon.com/blogs/database/how-letta-builds-production-ready-ai-agents-with-amazon-aurora-postgresql/)
- [Deep Dive: Letta Memory Models (Medium)](https://medium.com/@piyush.jhamb4u/stateful-ai-agents-a-deep-dive-into-letta-memgpt-memory-models-a2ffc01a7ea1)
- [MemGPT Paper: arXiv:2310.08560](https://arxiv.org/abs/2310.08560)

### Chroma
- [Chroma GitHub](https://github.com/chroma-core/chroma) -- 26.4k stars, Apache-2.0
- [Chroma Docs: Persistent Client](https://docs.trychroma.com/docs/run-chroma/persistent-client)
- [Chroma Docs: Embedding Functions](https://docs.trychroma.com/docs/embeddings/embedding-functions)
- [Chroma Docs: Usage Guide](https://docs.trychroma.com/guides)
- [Chroma Docs: Performance](https://docs.trychroma.com/guides/deploy/performance)
- [Chroma Cookbook: Clients](https://cookbook.chromadb.dev/core/clients/)
- [Chroma Cookbook: Storage Layout](https://cookbook.chromadb.dev/core/storage-layout/)
- [Chroma on PyPI](https://pypi.org/project/chromadb/) -- v1.5.2
- [ChromaDB Semantic Search with Metadata Filters (Medium)](https://medium.com/@sangal.sachin/chromadb-semantic-search-with-metadata-filters-using-python-456887e5e0cd)

### sqlite-vec
- [sqlite-vec GitHub](https://github.com/asg017/sqlite-vec) -- 7.1k stars, MIT/Apache-2.0
- [sqlite-vec on PyPI](https://pypi.org/project/sqlite-vec/) -- v0.1.6
- [sqlite-vec v0.1.0 Release Blog](https://alexgarcia.xyz/blog/2024/sqlite-vec-stable-release/index.html)
- [sqlite-vec Performance Analysis (Medium)](https://medium.com/@stephenc211/how-sqlite-vec-works-for-storing-and-querying-vector-embeddings-165adeeeceea)
- [SQLite vs Chroma Comparison (DEV)](https://dev.to/stephenc222/sqlite-vs-chroma-a-comparative-analysis-for-managing-vector-embeddings-4i76)
- [Embedded Intelligence: sqlite-vec (DEV)](https://dev.to/aairom/embedded-intelligence-how-sqlite-vec-delivers-fast-local-vector-search-for-ai-3dpb)

### Benchmarks and Comparisons
- [Vector Search Performance Benchmarks](https://www.newtuple.com/post/speed-and-scalability-in-vector-search)
- [Best Vector Databases 2026](https://www.firecrawl.dev/blog/best-vector-databases)
- [Survey of AI Agent Memory Frameworks](https://www.graphlit.com/blog/survey-of-ai-agent-memory-frameworks)
