Memory Has Tiers
"Never bulk-load everything. Tier it like S3 storage classes."
The Problem
read_graph() returns ALL 2,204 observations. 250KB. 62,500 tokens. Every. Single. Time.
Mem0: $20/mo. Zep: $49/mo. MemGPT: complex setup.
Your SQLite: $0/mo. 280 lines. Full control.
The Tier Architecture
HOT
get_recent(10)
~500 tokens
"What did I do today?"
↓ need more?
WARM
compact_graph(max=5)
~12,500 tokens
"Give me general context"
↓ need specific?
COLD
search_by_date / search_nodes
~1,000-3,000 tokens
"What happened Jul 18?"
↓ older than 60 days?
ARCHIVED
archive_old(60)
0 tokens (excluded)
Still searchable. Never auto-loaded.
DIY: Build Your Own
Two paths. Start local, scale when you need multi-device.
Locally First
SQLite + FTS5 ~/.memory.db MCP stdio (local)
Works on:
- Your Mac/Linux
- Your agent only
- Offline
Cost: $0/mo
Effort: 280 lines Python, 30 min
→ sync →
Multi-Device
CF Worker + D1 + Vectorize memory.yoursite.dev MCP over SSE/HTTP
Works on:
- Phone, other PCs
- Team sharing
- CI/CD agents
Cost: $0/mo (CF free tier)
Effort: +200 lines TS, 1 hour
What You Need
Stack: Python 3.11+ (or Node.js) + sqlite3 (built-in) + mcp SDK
Total: 280 lines across 3 files
schema.sql (64 lines)
CREATE TABLE entities (
name TEXT PRIMARY KEY,
entity_type TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE observations (
id INTEGER PRIMARY KEY,
entity_name TEXT REFERENCES entities(name),
content TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
archived INTEGER DEFAULT 0
);
CREATE VIRTUAL TABLE obs_fts USING fts5(content, entity_name);
-- 14 MCP tools: 9 backward-compatible + 5 new
-- search_by_date, get_recent, archive_old, stats, compact_graphWhy Not Mem0 / Zep?
| Feature | Mem0 | Zep | DIY SQLite |
|---|---|---|---|
| Cost | $20/mo | $49/mo | $0/mo |
| Data ownership | Theirs | Theirs | Yours |
| Offline | No | No | Yes |
| Customizable | API only | API only | Full source |
| Vendor lock-in | Yes | Yes | None |
| Setup time | 5 min | 10 min | 30 min |
| Lines of code | 0 | 0 | 280 |