-
Notifications
You must be signed in to change notification settings - Fork 0
Memory Tiers
Halfservers LLC edited this page Jan 22, 2026
·
1 revision
Deep dive into the tiered storage architecture.
Claude Code++ uses a tiered storage system optimized for different access patterns:
┌─────────────────────────────────────────────────────────┐
│ Hot Tier (Redis) │
│ < 1ms access │
│ Session cache, frequent items │
├─────────────────────────────────────────────────────────┤
│ Warm Tier │
│ ┌─────────────────────┬─────────────────────┐ │
│ │ Graphiti (Neo4j) │ LanceDB │ │
│ │ < 50ms access │ < 10ms access │ │
│ │ Relationships │ Semantic search │ │
│ └─────────────────────┴─────────────────────┘ │
├─────────────────────────────────────────────────────────┤
│ Cold Tier │
│ ┌─────────────────────┬─────────────────────┐ │
│ │ SQLite │ livegrep │ │
│ │ < 50ms access │ < 100ms access │ │
│ │ Full-text, meta │ Code search │ │
│ └─────────────────────┴─────────────────────┘ │
├─────────────────────────────────────────────────────────┤
│ Archive Tier (Vault) │
│ < 200ms access │
│ Human-readable documentation │
└─────────────────────────────────────────────────────────┘
| Property | Value |
|---|---|
| Storage | Redis |
| Latency | < 1ms |
| Capacity | ~1000 items |
| Persistence | Session-scoped |
| Requirement | Optional |
- Current session state
- Recently accessed memories
- Frequently used context
- Working file list
# Session state
session:{session_id} → {
"project_path": "/path",
"active_files": [...],
"context": {...}
}
# Hot memories
memory:{doc_id} → serialized document
# Access tracking
access:{doc_id} → access countREDIS_URL=redis://localhost:6379
REDIS_PASSWORD=optional
REDIS_DB=0- Direct SQLite queries (slightly slower)
- No session caching
- Core functionality unaffected
| Property | Value |
|---|---|
| Storage | Neo4j graph database |
| Latency | < 50ms |
| Capacity | Unlimited (relationship-based) |
| Persistence | Permanent |
| Requirement | Optional |
- Entity relationships ("User prefers dark mode")
- Decision tracking ("What led to choosing JWT?")
- Conceptual connections
- "Who/what/when/where" queries
// Entities
(:User)-[:PREFERS]->(:DarkMode)
(:Project {name: "api-gateway"})-[:USES]->(:JWT)
// Facts
(:Decision {
content: "Chose JWT for authentication",
timestamp: 2024-01-15
})NEO4J_URI=bolt://localhost:7687
NEO4J_USER=neo4j
NEO4J_PASSWORD=password
GRAPHITI_ENABLED=true- Relationship queries return empty
- Fall back to tag-based filtering
- Semantic search still works via LanceDB
| Property | Value |
|---|---|
| Storage | LanceDB (embedded) |
| Latency | < 10ms |
| Capacity | 100k+ vectors |
| Persistence | Permanent |
| Requirement | Optional |
- Semantic similarity search
- "Find memories like X"
- Conceptual matching
- Content clustering
Content → Embedding Model → Vector → LanceDB
↓
Query → Embedding → Nearest Neighbor Search → Results
LANCEDB_PATH=~/.claude-code-pp/memory/lancedb
EMBEDDING_PROVIDER=local # or openai, voyage| Provider | Quality | Speed | Cost |
|---|---|---|---|
| Local (nomic-embed) | Good | Fast | Free |
| OpenAI | Better | Medium | $$ |
| Voyage | Best | Medium | $$$ |
- Semantic search unavailable
- Fall back to full-text search
- Exact keyword matching only
| Property | Value |
|---|---|
| Storage | SQLite database |
| Latency | < 50ms |
| Capacity | Unlimited |
| Persistence | Permanent |
| Requirement | Required |
- Metadata storage
- Full-text search (FTS5)
- Document indexing
- Access pattern tracking
CREATE TABLE documents (
id TEXT PRIMARY KEY,
content TEXT,
doc_type TEXT,
source TEXT,
tags TEXT, -- JSON array
project TEXT,
importance REAL,
created_at TEXT,
updated_at TEXT,
accessed_at TEXT,
access_count INTEGER
);
CREATE VIRTUAL TABLE documents_fts USING fts5(
content, source, tags, project
);SQLITE_PATH=~/.claude-code-pp/memory/sqlite/memories.dbSQLite is the backbone - if it fails, memory is unavailable.
| Property | Value |
|---|---|
| Storage | Index files |
| Latency | < 100ms |
| Capacity | All indexed repositories |
| Persistence | Index-based |
| Requirement | Optional |
- Cross-repository code search
- Finding function definitions
- Pattern matching in code
- Code archaeology
# Find function definitions
code_search(query="async function.*authenticate")
# Find usages
code_search(query="authenticateRequest\\(")
# Search specific languages
code_search(query="class.*Controller", path_filter="*.ts")LIVEGREP_ENABLED=true
LIVEGREP_URL=http://localhost:8910
LIVEGREP_INDEX_PATH=/path/to/index- Code search limited to local grep
- Cross-repo search unavailable
| Property | Value |
|---|---|
| Storage | Markdown files |
| Latency | < 200ms |
| Capacity | Unlimited |
| Persistence | Permanent |
| Requirement | Required |
- Human-readable documentation
- Long-form notes
- Shareable content
- Version-controlled knowledge
vault/
├── code/ # Code snippets
├── notes/ # General notes
├── conversations/ # Conversation logs
├── references/ # Documentation
└── daily/ # Daily notes
---
tags:
- architecture
- auth
project: api-gateway
created: 2024-01-15
---
# Authentication Architecture
## Overview
...OBSIDIAN_VAULT_PATH=~/.claude-code-pp/memory/vaultThe system automatically routes queries to appropriate tiers:
def select_tier(query, query_type):
if mentions_relationships(query):
return [Graphiti, SQLite] # Relationship → Graphiti
if is_semantic(query_type):
return [LanceDB, SQLite] # Semantic → LanceDB
if is_code_query(query):
return [livegrep, Grep] # Code → livegrep
return [SQLite] # Default → SQLite FTSUse query patterns to hint at tier selection:
| Pattern | Routes To |
|---|---|
| "how does X relate to Y" | Graphiti |
| "similar to", "like when" | LanceDB |
| "where is X defined" | livegrep |
| Exact keywords | SQLite FTS |
Cold → Warm:
- Accessed > 5 times total
- Added to LanceDB for semantic search
Warm → Hot:
- Accessed > 3 times in current session
- Cached in Redis
Hot → Warm:
- Not accessed in 24 hours
- Removed from Redis cache
Warm → Cold:
- Not accessed in 7 days
- Embeddings may be archived
Every memory access updates:
-
accessed_attimestamp -
access_countcounter
These drive promotion/demotion decisions.
| Tier | Read | Write | Search | Best For |
|---|---|---|---|---|
| Redis | 0.5ms | 0.5ms | 1ms | Active session |
| LanceDB | 5ms | 50ms | 10ms | Semantic |
| Graphiti | 20ms | 100ms | 50ms | Relationships |
| SQLite | 10ms | 20ms | 50ms | Full-text |
| livegrep | N/A | N/A | 100ms | Code |
| Vault | 50ms | 100ms | N/A | Docs |
| Missing | Impact | Fallback |
|---|---|---|
| Redis | No hot cache | Direct SQLite |
| LanceDB | No semantic search | Full-text only |
| Graphiti | No relationships | Tag filtering |
| livegrep | No code search | Local grep |
Core (SQLite + Vault) is always required.
- Architecture - System overview
- Memory-MCP - Memory system docs
- Configuration - Setup options