Skip to content

Memory System

Mia maintains a persistent memory store that survives across sessions, restarts, and conversations. Facts, preferences, and project context are stored locally and injected into AI dispatches when relevant.

The memory system uses SQLite with FTS5 (full-text search) and BM25 ranking for relevance scoring. No vector databases or embeddings — just fast, local full-text search.

┌────────────────────────────────────────┐
│ Memory Store API │
├────────────────────────────────────────┤
│ store() · query() · delete() │
│ stats() · prune() │
├────────────────────────────────────────┤
│ LRU Query Cache │
│ (30-second TTL) │
├────────────────────────────────────────┤
│ SQLite + FTS5 (BM25) │
│ ~/.mia/memory.db │
└────────────────────────────────────────┘
TypeDescriptionExample
conversationChat historyPrior messages from a session
factExtracted knowledge”Uses pnpm workspaces”
contextCodebase/workspace info”React + TypeScript monorepo”
summaryConversation compactionCompressed prior conversation

After every successful AI dispatch, the MemoryExtractor middleware runs asynchronously:

  1. Analyzes the conversation turn for extractable facts
  2. Uses the active AI plugin to identify key information
  3. Stores facts with timestamps and metadata
  4. Non-blocking — doesn’t delay the response
{
"pluginDispatch": {
"memoryExtraction": {
"enabled": true,
"minDurationMs": 5000,
"maxFacts": 5
}
}
}

Store facts explicitly via CLI or chat:

Terminal window
# CLI command
mia memory add "prefers functional components over class components"
# In chat
/remember uses PostgreSQL for the main database

During context preparation, the ContextPreparer queries the memory store for facts relevant to the current prompt:

  1. Sanitize query — Strip special characters, join terms with OR
  2. FTS5 search — Full-text search with BM25 ranking
  3. Score and rank — Relevance score + recency weighting
  4. Inject into context — Top N results added to the plugin context

By default, up to 5 facts are injected per dispatch.

Repeated queries are cached to reduce database load:

  • Cache type: LRU (Least Recently Used)
  • TTL: 30 seconds
  • Max entries: Configurable (default varies)
  • Eviction: Automatic on TTL expiry or capacity overflow

Old entries are automatically pruned:

  • Default TTL: 30 days
  • Prune interval: Configurable (default: every few hours)
  • Entries older than TTL are permanently deleted

FIFO eviction prevents unbounded growth:

  • Default cap: 10,000 entries
  • When exceeded, oldest entries are deleted first
  • Configurable via memory.maxRows
Terminal window
mia memory list # Recent facts
mia memory search "react" # Search by keyword
mia memory stats # Counts by type, total size
{
"memory": {
"ttlDays": 30,
"queryCacheMaxEntries": 100,
"maxRows": 10000,
"pruneIntervalHours": 6
}
}