A Developer Built a Decay Plugin for mem0 — Because mem0 Doesn't Ship One
A GitHub issue filed against mem0 in early 2026 started with this observation:
"Mem0 has no built-in mechanism for memory expiration or decay. Over time, local deployments accumulate stale entries that degrade retrieval quality, inflate token usage, and create contradictions."
— mem0 issue #5330 (mem0-lifecycle plugin, HH1162)
The developer then published mem0-lifecycle — a standalone pip package implementing a forgetting-curve formula on top of mem0. It's a thoughtful piece of engineering. The problem is that it exists at all. Memory lifecycle management isn't a niche edge case; it's a foundational property of any system that accumulates state over time.
Dakera ships this natively. This post explains what that means in practice — and how it shapes real agent behavior.
Why Memory Accumulation Is a Production Problem
Any AI agent that stores memories without expiry develops a predictable failure mode: over time, the memory store becomes dominated by stale, contradicted, or low-signal entries. The agent "remembers" that the user preferred a setting they changed six months ago. It surfaces outdated project notes alongside current ones. Retrieval quality degrades, token costs rise, and the agent's behavior drifts from accurate to confidently wrong.
This isn't theoretical. It's the exact problem the mem0 issue author was solving for a production deployment. Their forgetting-curve plugin applies a custom importance decay function on a schedule — essentially replicating what a memory system should do internally.
A well-designed memory system needs three things built in:
- Decay — memories lose weight over time unless reinforced
- Importance weighting — not all memories matter equally at write time
- Cleanup — explicit tools to purge what shouldn't remain
Dakera ships all three as first-class features. No plugin required.
How Dakera's Native Decay Works
Step 1: Configure Decay Policy per Namespace
Decay behavior in Dakera is configured at the namespace level using the CLI. Each memory type (working, episodic, semantic, procedural) gets its own decay curve and TTL:
# Set aggressive exponential decay for working memory (e.g. scratch notes)
# and slower logarithmic decay for longer-lived episodic memories
dk namespace policy set my-agent \
--working-ttl 3600 \
--working-decay exponential \
--episodic-ttl 2592000 \
--episodic-decay logarithmic
Decay curve names are documented constants, not arbitrary strings:
| Curve | Behavior | Best for |
|---|---|---|
| exponential | Rapid initial decay, slows over time | Working memory, scratch notes |
| logarithmic | Slow initial decay, accelerates later | Project context, meeting summaries |
| linear | Constant decay rate | Session context with uniform aging |
| power_law | Heavy-tailed — strong memories persist much longer | User preferences with variable refresh |
| step | Discrete tiers (full strength → reduced → archived) | Customer interactions with SLA windows |
| flat | No decay — memories persist at full strength | Identity facts, permanent configuration |
You can also configure spaced repetition: memories that are frequently recalled get their decay clock reset, modeling the same reinforcement mechanism used in human long-term memory formation.
# Frequently-recalled memories gain a decay reprieve
dk namespace policy set my-agent \
--spaced-repetition-factor 1.5 \
--spaced-repetition-base-interval 86400
Step 2: Set Importance at Write Time
Decay operates on importance scores. When you store a memory, you set its starting importance explicitly — or let Dakera's ML classifier infer it from content characteristics (named entities, temporal references, quantitative data all score higher):
from dakera import DakeraClient
client = DakeraClient(base_url="http://localhost:3300", api_key="...")
# Critical preference — high importance, slow decay survival
client.store_memory(
agent_id="my-agent",
content="User's preferred timezone is Europe/Paris — always localize timestamps",
importance=0.9,
memory_type="semantic"
)
# Transient observation — low importance, will decay quickly
client.store_memory(
agent_id="my-agent",
content="User mentioned it was raining today",
importance=0.2,
memory_type="working"
)
The importance score is a first-class field on every memory. It's surfaced in the dashboard, filterable at recall time, and updated automatically by the decay engine on every background pass.
Step 3: Filter Recalls by Importance Floor
At recall time, you can filter out memories that have decayed below a threshold. This keeps stale context out of the agent's prompt automatically:
# Only retrieve memories with meaningful signal remaining
memories = client.recall(
agent_id="my-agent",
min_importance=0.4
)
# Or search semantically, filtering by importance simultaneously
results = client.search_memories(
agent_id="my-agent",
query="user preferences for report format",
top_k=5,
min_importance=0.3
)
Step 4: Explicit Cleanup When You Need It
Decay floors memories rather than deleting them outright (as of v0.9.10). When you want hard deletion, the SDK provides batch forget with filter predicates:
from dakera import BatchForgetRequest, BatchMemoryFilter
# Purge everything that's decayed to near-zero
client.batch_forget(BatchForgetRequest(
agent_id="my-agent",
filter=BatchMemoryFilter(
memory_type="working",
max_importance=0.05
)
))
The server emits forgotten events on the SSE stream for each deletion, and importance_updated events when importance is reduced by the background engine — so you can monitor memory lifecycle in real time.
What This Looks Like Side by Side
pip install mem0 mem0-lifecycle
from mem0 import Memory
from mem0_lifecycle import MemoryLifecycle
m = Memory()
lifecycle = MemoryLifecycle(client=m)
# Store — no importance parameter
m.add("User prefers dark mode", user_id="alice")
# Decay must be applied manually on a schedule
# Plugin implements forgetting curve externally
lifecycle.apply_forgetting_curve(user_id="alice")
# No built-in min_importance filter at recall
results = m.search("user preferences", user_id="alice")
pip install dakera
from dakera import DakeraClient
client = DakeraClient(base_url="http://localhost:3300",
api_key="...")
# Configure decay policy once (CLI, version-controlled)
# dk namespace policy set alice \
# --semantic-decay logarithmic \
# --semantic-ttl 7776000
# Store with importance — decay operates on this score
client.store_memory(
agent_id="alice",
content="User prefers dark mode",
importance=0.85,
memory_type="semantic"
)
# Recall with importance floor — stale memories filtered out
results = client.recall(
agent_id="alice",
min_importance=0.3
)
The mem0 example isn't wrong — it's a reasonable workaround. But it puts the burden of memory lifecycle management on application code. Every team using mem0 in production eventually writes their own version of the same plugin. Dakera treats this as infrastructure, not application logic.
Memory Lifecycle Is an Infrastructure Problem
mem0 is a solid project, and the community that built mem0-lifecycle clearly understands the problem deeply. The point isn't that their solution is bad — it's that memory decay is sufficiently fundamental that it should be part of the engine, not layered on top via pip.
Consider what happens when decay is external:
- Timing gaps — the forgetting curve only runs when your scheduler fires, not continuously. Memories stay artificially fresh between runs.
- No spaced repetition — externally applied decay can't easily account for access patterns. Dakera's engine sees every recall and adjusts accordingly.
- Visibility gap — external plugins don't emit structured lifecycle events. Dakera's dashboard shows
forgotten,importance_updated, andconsolidatedevents in real time. - Policy drift — decay configuration lives in application code, not alongside the memory store. Teams end up with inconsistent policies across services.
When decay is native, these problems disappear. The engine handles it continuously. Policy is version-controlled configuration applied to the namespace. The dashboard shows you what's happening in real time.
Background Consolidation: One Step Further
Dakera also ships background consolidation (COG-3) — a DBSCAN-based process that periodically identifies near-duplicate memories and merges them. This complements decay: where decay reduces the weight of stale memories, consolidation reduces redundancy in the ones that survive.
# Enable consolidation with 90% similarity threshold
dk namespace policy set my-agent \
--consolidation-enabled true \
--consolidation-threshold 0.90 \
--consolidation-interval-hours 24
Together, decay and consolidation keep your memory store lean and high-quality over time — without application-level cron jobs, external plugins, or custom cleanup scripts.
Try It
Self-host Dakera in minutes
Full memory lifecycle management — decay, importance scoring, consolidation — included in every deployment. No plugins required.
Get started →Related: Temporal Memory for AI Agents: How Decay and Importance Scoring Work · How Agent Memory Works