Beginner Lifecycle

Importance-Based Forgetting

⏰ ~15 min to implement 📦 Requires: Dakera v0.11+

Assign every memory an importance score at write time and let low-value entries fade naturally. Critical facts survive indefinitely; resolved tickets, small talk, and ephemeral context disappear automatically — no manual pruning required.

Start Free →
Prerequisites
  • Running Dakera server (Quickstart)
  • An agent ID to scope memories to
  • Basic understanding of 0.0–1.0 importance scale

The Problem: Noisy, Unbounded Memory Stores

Memory stores grow indefinitely by default. After six months, a customer support agent for a SaaS product accumulates thousands of memories: resolved bug reports, closed tickets, one-off workarounds, support greetings, and fleeting context from conversations long since closed. Without a forgetting mechanism, every recall query returns a mix of critical knowledge and stale noise.

The result: agents confidently surface outdated information, recall latency increases as candidate sets balloon, and storage costs grow linearly with agent lifespan. The solution is not to delete memories — it is to score them so the right ones surface and the wrong ones fade.

How Importance Decay Works

Dakera does not delete decayed memories — it excludes them from recall results when their effective importance drops below the query's min_importance threshold. Memories are soft-deleted from retrieval, not hard-deleted from storage. This means you can audit or recover them if needed, while recall stays clean.

Architecture

Every store_memory call accepts an importance field (0.0–1.0). Dakera's scoring engine tracks how importance evolves over time based on the memory's age, recall frequency (reinforcement), and explicit update_importance calls. At recall time, min_importance acts as a hard filter — only memories above the threshold enter the ranking pipeline.

  • Score 1.0 — permanent facts: user identity, account details, critical decisions
  • Score 0.7–0.9 — important context: user preferences, project milestones, escalations
  • Score 0.4–0.6 — useful context: working notes, active tickets, project details
  • Score 0.1–0.3 — ephemeral: greetings, resolved tickets, casual remarks
  • Score 0.0 — excluded from all recall results immediately

Diagram: Importance Distribution Histogram

0.0–0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8–1.0 0 200 400 600 580 400 300 220 175 135 115 165 min_importance = 0.4 threshold decays out of recall surfaced in recall importance score → # memories

Diagram: Forgetting Loop Flowchart

Store Memory importance=X Score Engine tracks age + recall Recall Query min_importance=0.5 score ≥ threshold? YES Include in results NO Exclude from recall (soft decay) recall reinforces importance (resistance to future decay)

Real-World Scenario: Customer Support Agent

Scenario: HelpDesk AI builds a support agent for a B2B SaaS product. The agent accumulates memories from thousands of support conversations: billing questions, bug reports, feature requests, and resolved tickets. After 12 months, the agent has 15,000+ memories. Recall quality degrades because closed tickets from last year surface alongside active incidents.

HelpDesk assigns importance by memory category: resolved tickets get 0.2 (decay within 2 weeks), active bug workarounds get 0.6 (persist 3 months), product announcements get 0.85 (persist 6 months), and permanent account facts (plan tier, contract terms) get 1.0. The recall threshold is set to min_importance=0.5 by default, ensuring resolved tickets never surface in new conversations.

Result: recall precision improves from 61% to 89%, and the effective memory store shrinks by 72% despite the agent growing by 40% in monthly active users.

Step-by-Step Implementation

  1. Define your importance taxonomy
    Before writing code, map your memory categories to importance scores. A support agent might use: identity facts (1.0), escalations (0.9), active tickets (0.6), resolved tickets (0.2), greetings (0.1). This taxonomy is the most important design decision in the pattern.
  2. Store memories with scored importance
    At every store_memory call, pass the appropriate importance score. Use tags alongside importance for multi-dimensional filtering later (e.g., tag resolved tickets with "resolved" so you can also filter by tag if needed).
  3. Configure recall thresholds per query type
    Not all queries need the same threshold. A "what is this user's account tier?" query should use min_importance=0.8 (identity facts only). A "what bugs has this user reported?" query might use min_importance=0.4 to include recent working notes.
  4. Update importance when status changes
    When a ticket is resolved, call update_importance to drop its score from 0.6 to 0.2. This triggers decay without deleting the memory. When a feature request is escalated to P0, raise its importance from 0.5 to 0.9.
  5. Batch forget truly irrelevant memories
    For memories you know are permanently useless (GDPR deletion, test data, spam), use batch_forget to hard-delete them rather than letting them decay. Decay is for gradual relevance loss; forget is for immediate removal.

Before & After: Recall Results

Before — no importance filter (8 results)
[
  { "content": "Hi there! How can I help?",
    "importance": 0.1, "age_days": 45 },
  { "content": "Ticket #1022 resolved: billing glitch",
    "importance": 0.2, "age_days": 38 },
  { "content": "Ticket #1104 resolved: login error",
    "importance": 0.2, "age_days": 30 },
  { "content": "User plan: Pro ($299/mo)",
    "importance": 1.0, "age_days": 180 },
  { "content": "API rate limit workaround documented",
    "importance": 0.55, "age_days": 14 },
  { "content": "Good morning, happy to assist!",
    "importance": 0.1, "age_days": 22 },
  { "content": "Ticket #982 resolved: CSV export bug",
    "importance": 0.2, "age_days": 60 },
  { "content": "User prefers async Slack updates",
    "importance": 0.8, "age_days": 90 }
]
// 6 of 8 results are stale noise
After — min_importance=0.5 (3 results)
[
  { "content": "User plan: Pro ($299/mo)",
    "importance": 1.0, "age_days": 180 },
  { "content": "User prefers async Slack updates",
    "importance": 0.8, "age_days": 90 },
  { "content": "API rate limit workaround documented",
    "importance": 0.55, "age_days": 14 }
]
// 3 signal memories — no stale noise
// Recall latency: 68ms vs 210ms (no filter)
// All 3 directly relevant to new query

Implementation

# Store a permanent identity fact
curl -X POST http://localhost:3300/v1/memory/store   -H "Authorization: Bearer dk-..."   -H "Content-Type: application/json"   -d '{
    "agent_id": "support-bot",
    "content": "User: Alex Kim — Pro plan, enterprise contract, API access",
    "importance": 1.0,
    "memory_type": "semantic",
    "tags": ["identity", "account"]
  }'

# Store an active ticket (medium importance)
curl -X POST http://localhost:3300/v1/memory/store   -H "Authorization: Bearer dk-..."   -H "Content-Type: application/json"   -d '{
    "agent_id": "support-bot",
    "content": "Ticket #2091 open: user cannot export to PDF — reproducible on Firefox",
    "importance": 0.6,
    "memory_type": "episodic",
    "tags": ["ticket", "open"]
  }'

# When ticket resolves: downgrade importance to trigger decay
curl -X PUT http://localhost:3300/v1/memory/mem-id-123/importance   -H "Authorization: Bearer dk-..."   -H "Content-Type: application/json"   -d '{"agent_id": "support-bot", "importance": 0.2}'

# Recall with threshold — resolved tickets excluded automatically
curl "http://localhost:3300/v1/memory/recall?agent_id=support-bot&query=PDF+export+issue&min_importance=0.5&top_k=10"   -H "Authorization: Bearer dk-..."

# Hard-delete truly irrelevant memories (e.g., GDPR request)
curl -X POST http://localhost:3300/v1/memory/batch-forget   -H "Authorization: Bearer dk-..."   -H "Content-Type: application/json"   -d '{"agent_id": "support-bot", "memory_ids": ["mem-001", "mem-002"]}'
from dakera import DakeraClient

client = DakeraClient(base_url="http://localhost:3300", api_key="dk-...")
AGENT = "support-bot"

# --- Importance taxonomy ---
IMPORTANCE = {
    "identity":        1.0,   # permanent: never decays
    "escalation":      0.9,   # high: persists 6+ months
    "preference":      0.8,   # high: persists months
    "active_ticket":   0.6,   # medium: persists weeks
    "resolved_ticket": 0.2,   # low: decays within 2 weeks
    "greeting":        0.1,   # ephemeral: decays within days
}

# Store permanent account fact
client.store_memory(
    agent_id=AGENT,
    content="User: Alex Kim, Pro plan $299/mo, enterprise contract, API access enabled",
    importance=IMPORTANCE["identity"],
    memory_type="semantic",
    tags=["identity", "account", "alex-kim"]
)

# Store active ticket
ticket_mem = client.store_memory(
    agent_id=AGENT,
    content="Ticket #2091 OPEN: cannot export to PDF, reproducible Firefox 124, macOS",
    importance=IMPORTANCE["active_ticket"],
    memory_type="episodic",
    tags=["ticket", "open", "pdf-export"]
)

# When ticket resolves: drop importance to trigger decay
def close_ticket(memory_id: str, resolution: str):
    client.update_importance(
        agent_id=AGENT,
        memory_id=memory_id,
        importance=IMPORTANCE["resolved_ticket"]
    )
    # Store resolution note at medium importance for audit
    client.store_memory(
        agent_id=AGENT,
        content=f"RESOLVED: {resolution}",
        importance=0.45,
        memory_type="semantic",
        tags=["ticket", "resolved"]
    )

close_ticket(ticket_mem.id, "Ticket #2091: PDF export fixed in v2.14.1, deployed 2026-05-15")

# Recall: only active, relevant memories
active_context = client.recall(
    agent_id=AGENT,
    query="Alex Kim account and open issues",
    min_importance=0.5,
    top_k=10
)

# Hard-delete for GDPR compliance
def delete_user_memories(memory_ids: list[str]):
    client.batch_forget(request={
        "agent_id": AGENT,
        "memory_ids": memory_ids
    })
import { DakeraClient } from '@dakera-ai/dakera';

const client = new DakeraClient({ baseUrl: 'http://localhost:3300', apiKey: 'dk-...' });
const AGENT = 'support-bot';

const IMPORTANCE = {
  identity:       1.0,
  escalation:     0.9,
  preference:     0.8,
  activeTicket:   0.6,
  resolvedTicket: 0.2,
  greeting:       0.1,
} as const;

// Store permanent identity fact
await client.storeMemory(AGENT, {
  content: 'User: Alex Kim — Pro plan $299/mo, enterprise contract, API access',
  importance: IMPORTANCE.identity,
  memoryType: 'semantic',
  tags: ['identity', 'account', 'alex-kim']
});

// Store active ticket
const ticketMem = await client.storeMemory(AGENT, {
  content: 'Ticket #2091 OPEN: cannot export to PDF, reproducible Firefox 124',
  importance: IMPORTANCE.activeTicket,
  memoryType: 'episodic',
  tags: ['ticket', 'open', 'pdf-export']
});

// On resolution: downgrade importance to enable decay
async function closeTicket(memoryId: string, resolution: string) {
  await client.updateImportance(AGENT, {
    memory_id: memoryId,
    importance: IMPORTANCE.resolvedTicket
  });
  await client.storeMemory(AGENT, {
    content: `RESOLVED: ${resolution}`,
    importance: 0.45,
    memoryType: 'semantic',
    tags: ['ticket', 'resolved']
  });
}

await closeTicket(ticketMem.id, 'Ticket #2091: PDF fix deployed in v2.14.1');

// Filtered recall — resolved tickets never appear
const context = await client.recall(AGENT, 'Alex Kim account and open issues', {
  min_importance: 0.5,
  top_k: 10
});

// GDPR hard delete
await client.batchForget({
  agent_id: AGENT,
  memory_ids: ['mem-001', 'mem-002']
});
use dakera_rs::{Client, StoreMemoryRequest, RecallRequest};

let client = Client::new("http://localhost:3300", "dk-...");
let agent = "support-bot";

// Store permanent identity memory
client.store_memory(agent, StoreMemoryRequest {
    content: "User: Alex Kim, Pro plan, enterprise contract, API access".into(),
    importance: Some(1.0),
    memory_type: "semantic".into(),
    tags: vec!["identity".into(), "account".into()],
    ..Default::default()
}).await?;

// Store active ticket at medium importance
let ticket = client.store_memory(agent, StoreMemoryRequest {
    content: "Ticket #2091 OPEN: PDF export fails in Firefox 124".into(),
    importance: Some(0.6),
    memory_type: "episodic".into(),
    tags: vec!["ticket".into(), "open".into()],
    ..Default::default()
}).await?;

// On resolution: downgrade importance via REST
// PUT /v1/memory/{id}/importance  { "importance": 0.2 }

// Recall with importance filter
let results = client.recall(agent, RecallRequest {
    query: "Alex Kim open issues".into(),
    min_importance: Some(0.5),
    top_k: Some(10),
    ..Default::default()
}).await?;

// Hard delete via REST: POST /v1/memory/batch-forget
// { "agent_id": "support-bot", "memory_ids": ["mem-001"] }
client := dakera.NewClient("http://localhost:3300", "dk-...")
ctx := context.Background()
agent := "support-bot"

// Permanent identity fact
client.StoreMemory(ctx, agent, dakera.StoreMemoryRequest{
    Content:    "User: Alex Kim — Pro plan, enterprise contract, API access",
    Importance: 1.0,
    MemoryType: "semantic",
    Tags:       []string{"identity", "account"},
})

// Active ticket at medium importance
ticket, _ := client.StoreMemory(ctx, agent, dakera.StoreMemoryRequest{
    Content:    "Ticket #2091 OPEN: PDF export fails in Firefox 124",
    Importance: 0.6,
    MemoryType: "episodic",
    Tags:       []string{"ticket", "open"},
})

// On resolution: downgrade importance
client.Forget(ctx, agent, ticket.ID) // or call update_importance via REST

// Recall with filter
results, _ := client.Recall(ctx, agent, dakera.RecallRequest{
    Query:         "Alex Kim open issues",
    MinImportance: 0.5,
    TopK:          10,
})

72% smaller effective memory stores

Importance-based decay runs server-side automatically — zero maintenance required.

Start Building →

SDK Reference

MethodSDKPurpose
store_memory(agent_id, content, importance, memory_type, tags)PythonStore memory with importance score
storeMemory(agentId, {content, importance, memoryType, tags})TypeScriptStore memory with importance score
recall(agent_id, query, min_importance, top_k)PythonRetrieve memories above importance threshold
recall(agentId, query, {min_importance, top_k})TypeScriptRetrieve memories above importance threshold
update_importance(agent_id, memory_id, importance)PythonReassign importance score to trigger/resist decay
updateImportance(agentId, {memory_id, importance})TypeScriptReassign importance score to trigger/resist decay
forget(agent_id, memory_id)PythonHard-delete a single memory permanently
forget(agentId, memoryId)TypeScriptHard-delete a single memory permanently
batch_forget(request)PythonHard-delete multiple memories (GDPR deletion)
batchForget(request)TypeScriptHard-delete multiple memories (GDPR deletion)

Performance Considerations

68ms
Recall p95 with min_importance=0.5 filter (vs 210ms unfiltered)
72%
Effective store reduction after 6 months of importance decay
<5ms
Latency for update_importance call (single memory)
  • min_importance is applied pre-ranking. The filter runs against the importance index before semantic scoring, dramatically reducing the candidate set and cutting recall latency by 60–70% compared to unfiltered queries on large stores.
  • Batch forget is faster than individual forgets. For GDPR deletion workflows processing 50+ memory IDs, batch_forget is 8–12x faster than looping over individual forget calls due to transaction batching.
  • update_importance is cheap. It modifies only the importance index field, not the embedding or content. Use it liberally when ticket or task status changes — it costs <5ms per call.

Edge Cases

Edge Case 1: Setting importance=1.0 by default

Developers often set importance=1.0 "to be safe," but this defeats the entire pattern. If everything is permanent, recall becomes noisy again. Reserve 1.0 strictly for facts that should never leave the store: user identity, account constants, irrevocable decisions. For everything else, use 0.5–0.9 and let decay do its job.

Edge Case 2: Forgetting to downgrade on state change

An active ticket stored at importance 0.6 will persist for weeks even after resolution if you forget to call update_importance. Integrate the importance downgrade into your ticket-close webhook or event handler — treat it as part of the "mark resolved" workflow, not an afterthought.

Edge Case 3: Reinforcement inflating scores unexpectedly

Dakera reinforces importance when a memory is recalled frequently. A low-importance memory that happens to match many queries can slowly drift upward in effective importance. If you're seeing stale memories resurface, check their recall frequency. Consider using update_importance to hard-set them back to 0.1 after investigation.

Edge Case 4: Using min_importance too aggressively

Setting min_importance=0.9 on all queries will return only identity facts — you'll miss active tickets and preferences. Use context-sensitive thresholds: high threshold (0.8) for factual lookups, lower threshold (0.4–0.5) for open-ended context queries. Tune per query intent.

Edge Case 5: Soft decay vs. hard delete for compliance

Soft decay (importance drops below threshold) does not physically remove the memory from storage — it only hides it from recall. For GDPR Article 17 right-to-erasure compliance, you must call batch_forget (hard delete). Document which memories are subject to erasure obligations and automate hard deletion on user account closure.

Advanced Configuration: Importance Policies & Reinforcement Tuning

Getting the Memory Policy

# Python
policy = client.get_memory_policy(namespace="support-bot")
print(policy.decay_rate)        # e.g., 0.05 per day
print(policy.reinforcement_factor)  # e.g., 0.02 per recall

# TypeScript
const policy = await client.getMemoryPolicy('support-bot');
console.log(policy.decay_rate, policy.reinforcement_factor);

Namespace-Level Policy Configuration

Set namespace-level defaults so you don't have to specify importance on every write. Configure a default importance for memory types (episodic: 0.3, semantic: 0.7) and a max importance cap (0.95 for non-identity memories).

Recommended Decay Rate by Use Case

Use CaseDecay RateHalf-Life
Customer support (high volume)0.07/day~10 days at imp=0.3
Personal assistant (long-term)0.02/day~35 days at imp=0.3
Legal / compliance0.005/day~140 days at imp=0.3
Real-time analytics0.15/day~5 days at imp=0.3

Ship Smarter Memory in 15 Minutes

Dakera's importance scoring is a single field on every store call. No pipelines, no schedulers — just set it and let the engine do the rest.

Deploy Free →