Intermediate Architecture

Hierarchical Memory

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

Structure your agent's memory the way the human brain does: fast-decaying working memory for active context, consolidated long-term memory for recurring facts, and permanent identity storage for what must never be forgotten. This pattern eliminates both information overload and premature forgetting in a single architecture.

Deploy Hierarchical Memory →
Prerequisites
  • Running Dakera server (see Quickstart)
  • API key with namespace management permissions
  • Understanding of memory importance scoring (0.0–1.0 scale)

Problem

Not all memories are equal. A user's name should persist forever, last week's conversation topics should fade gradually, and the current session's working context should be immediately available but ephemeral. Without differentiated storage, two failure modes emerge:

  • Recall pollution — stale working notes from 30 sessions ago surface alongside identity facts, confusing the agent's context window
  • Premature forgetting — applying aggressive decay equally removes genuinely important long-term knowledge alongside ephemeral chatter

The hierarchical pattern resolves both by applying different importance levels, memory types, and TTL strategies to each tier, so Dakera's ranking engine naturally surfaces what matters at any recall time.

How Dakera Ranks Memories

Dakera's recall endpoint combines semantic similarity with importance weighting. A permanent memory with importance 1.0 will outrank a semantically identical working note with importance 0.2 — so correct tier assignment automatically produces correct recall priority without any custom re-ranking logic.

Architecture

This pattern uses three memory tiers differentiated by importance level, memory type, and TTL. Each tier maps to a distinct phase of the information lifecycle.

Tier Structure

  • Tier 1 — Working Memory: importance 0.1–0.3, type working, TTL 1–4 hours. Captures current-session scratchpad: what the user just asked, which sub-task is active, draft answers in progress.
  • Tier 2 — Long-Term Memory: importance 0.5–0.8, type semantic, no hard TTL (natural decay applies). Holds consolidated knowledge: user's technical stack, recurring preferences, project context that accumulates across sessions.
  • Tier 3 — Permanent Memory: importance 1.0, tags ["identity","permanent"], TTL never. Core identity facts: user name, organization, role, verified preferences, critical constraints.

Data Flow Diagram

New Memory agent event / message Tier Classifier rules / LLM / heuristic assigns importance + type Tier 1 — Working importance: 0.1–0.3 | type: working TTL: 1–4h | auto-expires fast Tier 2 — Long-Term importance: 0.5–0.8 | type: semantic natural decay | weeks/months slow Tier 3 — Permanent importance: 1.0 | tags: identity no TTL | no decay ever ephemeral durable identity promote (N recalls) promote (verified) Recall — all tiers merged, ranked by importance x relevance Tier 3 always surfaces first for identity queries; Tier 1 wins for current-task queries

Ready to implement 3-tier memory in your agent?

Spin up Dakera in under 5 minutes with Docker — full hierarchical memory with zero config.

Deploy Hierarchical Memory →

Step-by-Step Implementation

  • Design your tier classification rules
    Decide what belongs in each tier. A simple heuristic: facts about who the user is (Tier 3), facts about what they work on (Tier 2), facts about what they said right now (Tier 1). You can implement this as a simple rule set, a scoring function, or a lightweight LLM call that outputs an importance score.
  • Store working memory with TTL
    At session start and during active conversation, store ephemeral notes with importance: 0.2, memory_type: "working", and ttl_seconds: 3600. These auto-expire so you never need to run a cleanup job for them.
  • Store long-term facts after consolidation
    At session end (or when a pattern repeats 3+ times), promote the insight to long-term with importance: 0.6–0.8 and memory_type: "semantic". No TTL needed — Dakera's natural decay will handle gradual fading over weeks if the fact is never recalled again.
  • Store permanent identity facts once
    When you first learn a user's name, role, or organization, store it with importance: 1.0 and tags: ["identity","permanent"]. Use update_memory if this changes — don't create duplicates.
  • Recall without tier filtering — importance does the work
    Use a single recall call per query. Dakera blends all three tiers in a single response, ranking by the product of semantic relevance and importance. For identity questions ("who am I talking to?") Tier 3 memories win. For current-task questions ("what was I just working on?") Tier 1 wins because they are more semantically similar.
  • Implement promotion logic
    Track recall counts per memory ID. When a Tier 1 memory is recalled 3+ times across sessions, call update_importance to raise it to 0.6 (Tier 2). When a Tier 2 fact is recalled 10+ times and never contradicted, promote to 1.0 with identity tags. This mirrors human memory consolidation during sleep.

Implementation

# --- TIER 1: Working memory (low importance, 1h TTL) ---
curl -X POST http://localhost:3300/v1/memory/store \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "assistant",
    "content": "User just asked about Python list comprehensions vs generator expressions",
    "importance": 0.2,
    "memory_type": "working",
    "ttl_seconds": 3600
  }'

# --- TIER 2: Long-term knowledge (medium importance, no TTL) ---
curl -X POST http://localhost:3300/v1/memory/store \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "assistant",
    "content": "User is a Python developer focused on data pipeline performance. Prefers concise idiomatic code. Uses pytest.",
    "importance": 0.7,
    "memory_type": "semantic",
    "tags": ["preferences", "tech-stack"]
  }'

# --- TIER 3: Permanent identity (importance 1.0, identity tags) ---
curl -X POST http://localhost:3300/v1/memory/store \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "assistant",
    "content": "User: Alex Chen. Role: Senior ML Engineer. Company: Acme Corp. Team: Data Infrastructure.",
    "importance": 1.0,
    "memory_type": "semantic",
    "tags": ["identity", "permanent"]
  }'

# --- Unified recall (all tiers merged, importance-ranked) ---
curl "http://localhost:3300/v1/memory/recall?agent_id=assistant&query=who+is+the+user+and+what+are+they+working+on&top_k=5" \
  -H "Authorization: Bearer dk-..."

# --- Promote Tier 1 to Tier 2 after repeated recall ---
curl -X PATCH http://localhost:3300/v1/memory/mem_abc123/importance \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{"agent_id": "assistant", "importance": 0.65}'
from dakera import DakeraClient
from collections import defaultdict

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

# Track recall counts for promotion logic
recall_counts = defaultdict(int)
TIER1_PROMOTE_THRESHOLD = 3   # promote to Tier 2 after 3 recalls
TIER2_PROMOTE_THRESHOLD = 10  # promote to Tier 3 after 10 recalls

def store_working(content: str, session_context: str = "") -> dict:
    """Tier 1: Ephemeral session scratchpad. Auto-expires in 1 hour."""
    return client.store_memory(
        agent_id="assistant",
        content=content,
        memory_type="working",
        importance=0.2,
        ttl_seconds=3600,
        tags=["working", "ephemeral"]
    )

def store_long_term(content: str, tags: list[str] = None) -> dict:
    """Tier 2: Consolidated knowledge. Survives weeks of inactivity."""
    return client.store_memory(
        agent_id="assistant",
        content=content,
        memory_type="semantic",
        importance=0.7,
        tags=tags or ["long-term"]
    )

def store_permanent(content: str) -> dict:
    """Tier 3: Identity facts. Never decays. Use sparingly."""
    return client.store_memory(
        agent_id="assistant",
        content=content,
        memory_type="semantic",
        importance=1.0,
        tags=["identity", "permanent"]
    )

def recall_with_promotion(query: str, top_k: int = 5) -> list:
    """Recall and auto-promote frequently accessed memories."""
    memories = client.recall(
        agent_id="assistant",
        query=query,
        top_k=top_k
    )

    for mem in memories:
        mem_id = mem["id"]
        recall_counts[mem_id] += 1
        current_importance = mem.get("importance", 0.2)

        # Promote Tier 1 -> Tier 2 if recalled frequently
        if current_importance < 0.5 and recall_counts[mem_id] >= TIER1_PROMOTE_THRESHOLD:
            client.update_importance(
                agent_id="assistant",
                memory_id=mem_id,
                importance=0.65
            )
            print(f"Promoted memory {mem_id} to Tier 2 (recalled {recall_counts[mem_id]}x)")

        # Promote Tier 2 -> Tier 3 if very frequently recalled
        elif 0.5 <= current_importance < 0.95 and recall_counts[mem_id] >= TIER2_PROMOTE_THRESHOLD:
            client.update_importance(
                agent_id="assistant",
                memory_id=mem_id,
                importance=1.0
            )
            client.update_memory(
                agent_id="assistant",
                memory_id=mem_id,
                tags=["identity", "permanent"]
            )
            print(f"Promoted memory {mem_id} to Tier 3 (recalled {recall_counts[mem_id]}x)")

    return memories

# --- Example usage ---

# On first meeting the user
store_permanent("User: Alex Chen, Senior ML Engineer at Acme Corp, Data Infrastructure team")

# During current session
store_working("User is debugging a memory leak in their Spark job — heap usage grows 2x per batch")
store_working("User mentioned the job processes ~50M records per day")

# After the session — consolidate what we learned
store_long_term(
    "Alex works on Spark data pipelines processing 50M records/day. "
    "Has recurring memory leak issues. Prefers Python solutions over Scala.",
    tags=["tech-stack", "pain-points"]
)

# Recall in the next session
context = recall_with_promotion("what is the user working on and what problems do they have", top_k=8)
for mem in context:
    print(f"[{mem['importance']:.1f}] {mem['content'][:80]}")
import { DakeraClient } from '@dakera-ai/dakera';

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

const TIER1_THRESHOLD = 3;
const TIER2_THRESHOLD = 10;
const recallCounts = new Map<string, number>();

// Tier 1: Working memory — expires in 1 hour
async function storeWorking(content: string): Promise<{ id: string }> {
  return client.storeMemory('assistant', {
    content,
    memoryType: 'working',
    importance: 0.2,
    ttl_seconds: 3600,
    tags: ['working', 'ephemeral']
  });
}

// Tier 2: Long-term semantic memory — slow natural decay
async function storeLongTerm(content: string, tags: string[] = []): Promise<{ id: string }> {
  return client.storeMemory('assistant', {
    content,
    memoryType: 'semantic',
    importance: 0.7,
    tags: ['long-term', ...tags]
  });
}

// Tier 3: Permanent identity — never decays
async function storePermanent(content: string): Promise<{ id: string }> {
  return client.storeMemory('assistant', {
    content,
    memoryType: 'semantic',
    importance: 1.0,
    tags: ['identity', 'permanent']
  });
}

// Recall with automatic promotion
async function recallWithPromotion(query: string, topK = 5) {
  const memories = await client.recall('assistant', query, { top_k: topK });

  for (const mem of memories) {
    const count = (recallCounts.get(mem.id) ?? 0) + 1;
    recallCounts.set(mem.id, count);

    if (mem.importance < 0.5 && count >= TIER1_THRESHOLD) {
      // Promote Tier 1 -> Tier 2
      await client.updateImportance('assistant', { memory_id: mem.id, importance: 0.65 });
      console.log(`Promoted ${mem.id} to Tier 2`);
    } else if (mem.importance >= 0.5 && mem.importance < 0.95 && count >= TIER2_THRESHOLD) {
      // Promote Tier 2 -> Tier 3
      await client.updateImportance('assistant', { memory_id: mem.id, importance: 1.0 });
      await client.updateMemory('assistant', mem.id, { tags: ['identity', 'permanent'] });
      console.log(`Promoted ${mem.id} to Tier 3 (permanent)`);
    }
  }

  return memories;
}

// --- Usage ---

// First session: store identity
await storePermanent('User: Alex Chen, Senior ML Engineer at Acme Corp');

// During session: working scratchpad
await storeWorking('User debugging Spark memory leak — heap grows 2x per batch cycle');
await storeWorking('Spark job processes ~50M records/day on 8-node cluster');

// End of session: consolidate to long-term
await storeLongTerm(
  'Alex runs Spark pipelines processing 50M records/day. Recurring OOM issues. Prefers Python.',
  ['tech-stack', 'pain-points']
);

// Next session recall
const context = await recallWithPromotion('what is the user building and what problems do they face', 8);
context.forEach(m => console.log(`[${m.importance.toFixed(1)}] ${m.content.substring(0, 80)}`));
use dakera_rs::{Client, StoreMemoryRequest, RecallRequest, UpdateMemoryRequest};
use std::collections::HashMap;

let client = Client::new("http://localhost:3300", "dk-...");
let mut recall_counts: HashMap<String, u32> = HashMap::new();

// Tier 1: Working memory — auto-expires in 1 hour
client.store_memory("assistant", StoreMemoryRequest {
    content: "User debugging Spark memory leak — heap grows 2x per batch cycle".into(),
    memory_type: Some("working".into()),
    importance: Some(0.2),
    ttl_seconds: Some(3600),
    tags: vec!["working".into(), "ephemeral".into()],
    ..Default::default()
}).await?;

// Tier 2: Long-term semantic — slow decay
client.store_memory("assistant", StoreMemoryRequest {
    content: "Alex runs Spark pipelines processing 50M records/day. OOM issues recurring.".into(),
    memory_type: Some("semantic".into()),
    importance: Some(0.7),
    tags: vec!["tech-stack".into(), "pain-points".into()],
    ..Default::default()
}).await?;

// Tier 3: Permanent identity — no decay
client.store_memory("assistant", StoreMemoryRequest {
    content: "User: Alex Chen, Senior ML Engineer at Acme Corp, Data Infrastructure".into(),
    memory_type: Some("semantic".into()),
    importance: Some(1.0),
    tags: vec!["identity".into(), "permanent".into()],
    ..Default::default()
}).await?;

// Recall all tiers in one call — importance ranking is automatic
let memories = client.recall("assistant", RecallRequest {
    query: "who is the user and what are they working on".into(),
    top_k: Some(8),
    ..Default::default()
}).await?;

// Promotion logic
for mem in &memories {
    let count = recall_counts.entry(mem.id.clone()).or_insert(0);
    *count += 1;

    if mem.importance < 0.5 && *count >= 3 {
        client.update_memory("assistant", &mem.id, UpdateMemoryRequest {
            importance: Some(0.65),
            ..Default::default()
        }).await?;
        println!("Promoted {} to Tier 2", mem.id);
    }
}
package main

import (
    "context"
    "fmt"
    dakera "github.com/dakera-ai/dakera-go"
)

func main() {
    client := dakera.NewClient("http://localhost:3300", "dk-...")
    ctx := context.Background()
    recallCounts := make(map[string]int)

    // Tier 3: Permanent identity — store once, recall forever
    client.StoreMemory(ctx, "assistant", dakera.StoreMemoryRequest{
        Content:    "User: Alex Chen, Senior ML Engineer at Acme Corp",
        MemoryType: "semantic",
        Importance: 1.0,
        Tags:       []string{"identity", "permanent"},
    })

    // Tier 1: Working memory — expires in 1 hour
    client.StoreMemory(ctx, "assistant", dakera.StoreMemoryRequest{
        Content:    "User debugging Spark memory leak — heap grows 2x per batch",
        MemoryType: "working",
        Importance: 0.2,
        TTLSeconds: 3600,
        Tags:       []string{"working", "ephemeral"},
    })

    // Tier 2: Long-term knowledge — slow natural decay
    client.StoreMemory(ctx, "assistant", dakera.StoreMemoryRequest{
        Content:    "Alex runs Spark pipelines, 50M records/day, OOM issues, prefers Python",
        MemoryType: "semantic",
        Importance: 0.7,
        Tags:       []string{"tech-stack", "pain-points"},
    })

    // Single recall call covers all tiers
    memories, _ := client.Recall(ctx, "assistant", dakera.RecallRequest{
        Query: "who is the user and what are they working on",
        TopK:  8,
    })

    for _, mem := range memories {
        recallCounts[mem.ID]++
        fmt.Printf("[%.1f] %s
", mem.Importance, mem.Content[:min(len(mem.Content), 80)])

        // Promote if recalled frequently
        if mem.Importance < 0.5 && recallCounts[mem.ID] >= 3 {
            client.UpdateMemory(ctx, "assistant", mem.ID, dakera.UpdateMemoryRequest{
                Importance: 0.65,
            })
        }
    }
}

Before / After Memory State

Here is what the memory store looks like before applying the hierarchical pattern (flat, no tier differentiation) versus after correct tier assignment.

Before — flat, undifferentiated
[importance: 0.5] User name is Alex
[importance: 0.5] User asked about list comprehensions
[importance: 0.5] Python is user's language
[importance: 0.5] User mentioned Spark job timeout
[importance: 0.5] User asked about generators yesterday
[importance: 0.5] Alex works at Acme Corp
[importance: 0.5] Discussed memory leak in session 3
[importance: 0.5] User prefers concise code

Problem: stale conversation notes rank equally with identity facts. Recall for "who is the user?" returns random noise from 8 sessions ago.

After — tiered, importance-ranked
[1.0][identity] Alex Chen, Sr. ML Eng, Acme Corp
[1.0][identity] Alex's team: Data Infrastructure
[0.8][long-term] Spark pipelines, 50M records/day
[0.7][long-term] Prefers Python, concise idioms
[0.7][long-term] Recurring OOM in batch jobs
[0.2][working] Debugging Spark heap leak (this session)
[0.2][working] Asked about list comprehensions today
  -- EXPIRED -- User asked about generators (3d ago)

Result: identity surfaces first, working notes auto-expire, long-term facts persist with appropriate weight. Recall is precise and noise-free.

SDK Reference

OperationPythonTypeScriptPurpose
Store workingstore_memory(..., importance=0.2, ttl_seconds=3600)storeMemory(..., {importance: 0.2, ttl_seconds: 3600})Tier 1 ephemeral note
Store long-termstore_memory(..., importance=0.7, memory_type="semantic")storeMemory(..., {importance: 0.7, memoryType: "semantic"})Tier 2 durable fact
Store permanentstore_memory(..., importance=1.0, tags=["identity"])storeMemory(..., {importance: 1.0, tags: ["identity"]})Tier 3 identity fact
Recall all tiersrecall(agent_id, query, top_k=8)recall(agentId, query, {top_k: 8})Merged importance-ranked results
Promote tierupdate_importance(agent_id, memory_id, importance=0.7)updateImportance(agentId, {memory_id, importance: 0.7})Advance memory to higher tier
Update memoryupdate_memory(agent_id, memory_id, tags=["identity"])updateMemory(agentId, memoryId, {tags: ["identity"]})Add identity tags on promotion
Filter by typerecall(..., memory_type="semantic")recall(..., {memory_type: "semantic"})Query specific tier only

Real-World Example: Personal Coding Assistant

Consider an AI coding assistant that helps the same developer, Alex, across hundreds of sessions over 6 months. Here is exactly how hierarchical memory maps to the product experience:

Session 1 — First contact

Alex introduces herself: "I'm Alex, Senior ML Engineer at Acme. I work on Spark pipelines." The agent immediately stores this as Tier 3 identity (importance 1.0). It also stores the current conversation topic — debugging a memory leak — as Tier 1 working memory (importance 0.2, TTL 2h).

Sessions 2–5 — Pattern recognition

Alex returns with different problems, but consistently mentions Python, Spark, and OOM errors. The promotion heuristic detects these facts being recalled 3+ times and promotes them from Tier 1 (generated fresh each session) to Tier 2 long-term storage (importance 0.7). The agent now says "I know you work with Spark — are you seeing the heap growth issue again?" without being told.

Session 50 — Identity confirmation

After 50 sessions, "Alex is a Spark developer" has been recalled 47 times without contradiction. Promotion logic elevates it to Tier 3 (importance 1.0). Now even if Alex starts a session with a completely unrelated question, her identity context loads first in every recall, enabling perfectly personalized responses from the very first message.

Promotion Pattern Tip

Don't rely on manual tier promotion — build it into your recall wrapper. Every time a memory is returned by recall(), increment its recall count. At thresholds (3x for Tier 1->2, 10x for Tier 2->3), call update_importance() automatically. This mirrors sleep-based memory consolidation and keeps your store self-organizing.

Memory Recall Flow by Tier

This sequence diagram shows how Dakera fans out a recall request across all three tiers simultaneously, merging results by importance score before returning to the agent.

Agent Dakera API Working Long-term Permanent recall(query, top_k=10) fan out: working fan out: long-term fan out: permanent 0-3 results (imp<0.4) 0-6 results (imp 0.5-0.8) 0-4 results (imp=1.0) merge + rank top 10 ranked by importance inject into prompt context

Performance Considerations

<2ms
TTL expiry overhead per query
~70%
Storage reduction from Tier 1 auto-expiry
3–5x
Recall precision improvement vs flat store

Tier 1 TTL expiry has no runtime cost — Dakera expires memories lazily on read, adding less than 2ms per query to check TTL timestamps. The bigger win is storage: in a 6-month production deployment, Tier 1 working memories account for ~70% of write volume but are almost entirely eliminated by TTL before ever being recalled more than once, dramatically reducing index size for Tiers 2 and 3.

Recall latency scales with index size. By keeping your permanent store small (Tier 3 should have fewer than 50 facts per user), you maintain sub-10ms P99 recall latency even at 10,000+ users on a single Dakera instance.

Edge Cases

1. Contradictory Tier 3 facts

A user changes jobs. You have [identity] Alex works at Acme Corp stored as importance 1.0. If you store a new Tier 3 memory [identity] Alex now works at Betacorp, both will surface on recall, confusing the agent. Fix: before storing a new identity fact, search for conflicting memories first using search_memories(), then call forget() on the superseded one.

2. Tier inflation via over-aggressive promotion

If your promotion threshold is too low (e.g., promote after 1 recall), every working note ends up in Tier 2 within a week, defeating the purpose of the hierarchy. Fix: require at least 3 recalls across different sessions (not the same session) before promoting. Track session IDs alongside recall counts.

3. TTL drift across timezones

TTL is calculated from storage time. If a user in Tokyo stores a working memory at 11 PM and your server is in UTC, the memory expires at the "wrong" local time. Fix: for session-scoped working memory, use a TTL of 6–8 hours rather than 1 hour to ensure a full work session is always covered regardless of timezone.

4. Recall returns only Tier 1 for current-session queries

If the user's current question is semantically very specific (e.g., "what's the exact command I just ran?"), the recall might return only Tier 1 working memories even with importance weighting. Fix: use a two-pass strategy — first recall with min_importance=0.8 to get identity context, then a second recall without the filter for current-session relevance, and merge the results.

5. Stale long-term facts that were never explicitly contradicted

Long-term memories decay naturally but slowly. A fact like "Alex uses Python 3.9" stored 8 months ago may now be wrong (she upgraded to 3.12) but hasn't been explicitly updated. Fix: at the start of each session, run a targeted recall for technology-stack facts and ask the user to confirm any that are older than 90 days. Store the confirmation timestamp as metadata.

Common Mistake: Permanent Memory Sprawl

Resist the temptation to store everything as importance 1.0. Permanent memory should contain only verified identity facts — name, role, organization, critical constraints. Every additional Tier 3 memory competes in the top-ranked recall results and dilutes the precision that makes the tier valuable. A good rule: fewer than 10 permanent memories per user at any given time.

Advanced Configuration — Tier Thresholds & Decay Tuning

Custom Promotion Thresholds by Domain

Different applications need different promotion aggressiveness:

  • Customer support agents: promote to Tier 2 after 2 recalls (high user turnover, need quick personalization), never auto-promote to Tier 3 (let humans curate permanent data)
  • Personal assistant agents: promote to Tier 2 after 5 recalls (slow relationship building), promote to Tier 3 after 20 recalls (very conservative about permanence)
  • Code review agents: promote coding style preferences to Tier 2 after 3 recalls, architecture decisions to Tier 2 immediately (high-value signals)

Two-Tier vs Three-Tier

For simpler agents, two tiers (working + permanent) may suffice. Use importance: 0.5 as the dividing line. Working memory uses TTL, permanent uses importance 1.0 + identity tags. Skip the intermediate Tier 2 and its promotion logic entirely.

Memory Type Reference

# memory_type values and their semantic meaning in Dakera:
# "working"   — short-lived operational context, TTL-eligible
# "semantic"  — factual knowledge, subject to natural decay
# "episodic"  — event records with timestamps (use for audit trails)
# "procedural" — how-to knowledge, step sequences, skill memories

# For hierarchical pattern:
# Tier 1: memory_type="working"   + low importance + TTL
# Tier 2: memory_type="semantic"  + medium importance
# Tier 3: memory_type="semantic"  + importance=1.0 + identity tags

Batch Tier Assignment at Ingestion

from dakera import DakeraClient, BatchRecallRequest

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

# Classify and store in batch at session end
memories_to_store = [
    {"content": "User asked about list comprehensions", "tier": 1},
    {"content": "User prefers functional programming style", "tier": 2},
]

for m in memories_to_store:
    importance = {1: 0.2, 2: 0.7, 3: 1.0}[m["tier"]]
    ttl = 3600 if m["tier"] == 1 else None
    client.store_memory(
        agent_id="assistant",
        content=m["content"],
        importance=importance,
        ttl_seconds=ttl
    )

Deploy Hierarchical Memory in Your Agent

Start with a free Dakera instance. Three tiers configured and running in under 30 minutes — with automatic TTL expiry and importance-ranked recall built in.

Get Started Free →