DEV Community

mage0535
mage0535

Posted on • Originally published at hermes-agent.nousresearch.com

Hot Cache: A P0 Lever for KMM Enhancement in Hermes-Memory-Installer

The latest docs for hermes-memory-installer codify a claude-obsidian fusion, outlining six patterns for Knowledge Model Memory (KMM) enhancement. Hot Cache is designated Priority 0 (P0)—the critical path for reducing latency and scaling context recall. If you're wiring Claude to an Obsidian vault for persistent memory, this is the lever you pull first.

Hot Cache addresses a fundamental bottleneck in KMM: retrieval speed. When a memory system references an Obsidian note during a Claude session, hitting disk on every access kills responsiveness. The Hot Cache pattern keeps frequently referenced memories in an in-memory store, keyed by a hash of the note's path and a timestamp of last use. The P0 rating reflects that without this cache, no other optimization (prefetch, compression, weighting) matters—the pipeline stalls before it starts.

How it works in practice. Hermes-memory-installer defines a HotCache class that wraps the memory retrieval layer. On read, it checks the cache before falling back to the Obsidian vault. On write (e.g., a new Claude session note), it updates both the vault and the cache. The TTL and eviction policy are configurable, but the default uses a LRU strategy tuned for typical conversation flow—around 500 entries with a 30-minute idle timeout.

Here's the core implementation from the latest release:

class HotCache:
    def __init__(self, vault: ObsidianVault, max_entries: int = 500, ttl: int = 1800):
        self.vault = vault
        self.cache = LRUCache(max_entries)
        self.ttl = ttl

    def get(self, note_path: str) -> dict | None:
        entry = self.cache.get(note_path)
        if entry and time.monotonic() - entry["ts"] < self.ttl:
            return entry["data"]
        data = self.vault.read(note_path)
        if data:
            self.cache.put(note_path, {"data": data, "ts": time.monotonic()})
        return data
Enter fullscreen mode Exit fullscreen mode

The LRUCache is a bounded dict—no heavy dependencies. The ttl check ensures stale notes don't pollute memory, but because Obsidian vaults change mostly via Claude's own writes, staleness is rare in practice. The P0 aspect is the fallthrough: every get that hits cached data avoids a filesystem read, which for plain-text markdown notes can drop median lookup from ~12ms to ~0.2ms.

What about polyglot notes? If your KMM uses embeddings or graph links, the Hot Cache stores the raw note body plus any precomputed vector hash. The pattern extends naturally: you can cache the embedded representation (e.g., a numpy array) alongside the text. The default config avoids this to keep memory overhead low—vector caches are a separate P1 pattern.

Failure modes. The cache is active but non-critical for correctness. If a note is edited externally in Obsidian while the cache holds a stale copy, next Claude interaction will still get the old version until the TTL expires or a write invalidates it. This is acceptable for a P0—it's an optimization, not a consistency layer. For full sync, the hermes-memory-installer hooks into Obsidian's file watcher, but that's a separate pattern.

Other patterns in the fusion. The docs list six: Hot Cache (P0), Vector Prefetch (P1), Graph Indexing (P1), Session Compaction (P2), Cold Storage Bucketing (P2), and Context Triage (P3). Each addresses a dimension of KMM overhead, but Hot Cache is the gate. Without it, the remaining patterns fight I/O latency that dwarfs their benefits.

If you're integrating this into your own toolchain, focus on the cache hit rate. The installer exposes a --hot-cache-size flag and a metric endpoint to monitor misses. Tweaking the TTL and capacity per workload is expected: long-form research sessions benefit from larger caches, while quick Q&A works fine with the default.

The claude-obsidian fusion hits a pragmatic tradeoff: keep the vault as source of truth, but don't let its access pattern kill responsiveness. Hot Cache is the simplest concrete step—ship it first, then wire the rest.

Top comments (0)