Memory Scoring & Decay
ZeroMemory uses a blended scoring algorithm to rank memories during recall. This ensures the most relevant, important, and recent memories surface first.
Blended Scoring Formula
final_score = (similarity × W_sim) + (importance × W_imp) + (recency × W_rec)
Default weights:
- W_sim = 0.5 (semantic similarity)
- W_imp = 0.3 (importance)
- W_rec = 0.2 (recency)
Similarity Score (0.0–1.0)
Cosine distance between the query embedding and each memory's embedding. Powered by pgvector HNSW indexes for sub-millisecond search.
Importance Score (0.0–1.0)
Set at storage time via the importance parameter. Can also be adjusted:
- Auto-boost: Importance increases by 0.05 each time a memory is accessed (capped at 1.0)
- Manual: Update via the API
Recency Score (0.0–1.0)
Decays over time using exponential decay based on days since last access (not creation):
effective_importance = importance × exp(-decay_rate × days_since_access)
Per-Type Decay Rates
| Memory Type | Decay Rate | Half-Life | Effective Zero (~0.05) |
|---|---|---|---|
| Working | 0.5 | ~1.4 days | ~6 days |
| Episodic | 0.1 | ~6.9 days | ~30 days |
| Semantic | 0.02 | ~34.7 days | ~150 days |
Every time a memory is accessed (recalled, searched, or referenced), days_since_access resets to 0. Frequently-used memories never decay.
Soft-Delete Threshold
Memories whose effective importance drops below 0.05 are soft-deleted (state → archived). They remain in the database but are excluded from recall results. Consolidation can still reference archived memories.
Retention Examples
A semantic memory with importance 0.8:
- After 1 week:
0.8 × exp(-0.02 × 7)= 0.69 (still active) - After 1 month:
0.8 × exp(-0.02 × 30)= 0.44 (still active) - After 5 months:
0.8 × exp(-0.02 × 150)= 0.04 (archived)
An episodic memory with importance 0.5:
- After 1 day:
0.5 × exp(-0.1 × 1)= 0.45 (active) - After 1 week:
0.5 × exp(-0.1 × 7)= 0.25 (active) - After 1 month:
0.5 × exp(-0.1 × 30)= 0.02 (archived)
Memory Tiers & Consolidation
| Tier | Typical Lifespan | Consolidation |
|---|---|---|
| Working | Hours | Auto-consolidates to episodic after session ends |
| Episodic | Days–weeks | Frequently accessed episodic memories promote to semantic |
| Semantic | Permanent | Core knowledge — highest importance, slowest decay |
Consolidation happens automatically based on:
- Access frequency: Memories accessed 3+ times promote faster
- Importance threshold: Memories with importance > 0.7 promote faster
- Time in tier: Working memories consolidate after ~4 hours of inactivity
Example: How Scoring Works
A user asks: "What programming language does Alice prefer?"
| Memory | Similarity | Importance | Recency | Final Score |
|---|---|---|---|---|
| "Alice prefers Python for backend" | 0.92 | 0.8 | 0.9 | 0.88 |
| "Alice mentioned Rust is interesting" | 0.75 | 0.4 | 0.3 | 0.56 |
| "Backend team uses Python and FastAPI" | 0.70 | 0.5 | 0.7 | 0.64 |
The first memory wins because it has high similarity AND high importance AND was accessed recently.
Tuning Tips
- Set importance explicitly for critical facts (preferences, decisions, constraints)
- Use memory_type wisely:
workingfor current task context,episodicfor interactions,semanticfor permanent knowledge - Tag memories so you can filter during recall for better precision
- Reflect periodically: The
/reflectendpoint consolidates and synthesizes patterns
GraphRAG Scoring
When using the GraphRAG endpoint, an additional graph proximity score is blended:
graphrag_score = (vector_score × (1 - graph_weight)) + (graph_proximity × graph_weight)
Default graph_weight is 0.3 (70% vector, 30% graph). Tune higher for queries about relationships, lower for topical searches.