LLM Memory Systems: Building AI That Remembers
Back to all articles
AI Engineering
19 min read11 min read

LLM Memory Systems: Building AI That Remembers

From conversation history to long-term memory. Architectures for building AI systems that maintain context across sessions, learn from interactions, and personalize over time.

Debasish Maji
Debasish Maji
AI Engineering Lead
May 2, 2026
MemoryContextPersonalizationArchitectureState

The Memory Problem

LLMs have no memory. Every request starts fresh.

This fundamental limitation creates jarring user experiences. Your AI assistant forgets your name between sessions. Your support bot asks the same clarifying questions every time. Your coding assistant cannot remember your project conventions.

Building memory into AI systems transforms them from stateless tools into persistent collaborators.

•••

Memory Types

Classification

Memory TypeScopeDurationExample
Working memoryCurrent conversationMinutesChat history
Short-term memorySessionHoursSession context
Long-term memoryUserMonths/YearsPreferences, history
Semantic memoryKnowledgePermanentFacts, procedures
Episodic memoryEventsVariablePast interactions

Memory Characteristics

TypeWrite FrequencyRead FrequencySize
WorkingEvery turnEvery turnSmall (tokens)
Short-termPer sessionStart of sessionMedium (KB)
Long-termPer interactionPer requestLarge (MB)
SemanticInfrequentFrequentVery large (GB)
•••

Working Memory: Conversation Context

Context Window Management

StrategyImplementationUse Case
Full historySend all messagesShort conversations
Sliding windowLast N messagesLong conversations
SummarizationCompress older contextVery long conversations
HybridRecent full + older summarizedBest of both

Window Sizing

Context LengthMessages (avg 100 tokens)Strategy
4K tokens~30 messagesFull history
8K tokens~60 messagesFull history
32K tokens~250 messagesFull or sliding
128K tokens~1000 messagesUsually full

Summarization Approaches

ApproachQualityCostLatency
LLM summarizationHighMedium500ms
Extractive summaryMediumLow50ms
Rolling summaryHighHighPer-turn
HierarchicalVery highHighVariable

Rolling Summary Implementation

StepActionOutput
1Keep last N messages verbatimRecent context
2Summarize messages N+1 to N+MSummary block
3On new message, update summaryUpdated summary
4Combine: summary + recentFull context
•••

Short-Term Memory: Session State

Session Data

Data TypeExampleStorage
User identityName, roleSession store
Task contextCurrent goalSession store
Working documentsDraft, editsSession store
PreferencesFormat, toneSession store

Session Architecture

ComponentTechnologyPurpose
Session IDUUIDIdentify session
Session storeRedisFast access
TTL24 hoursAuto-cleanup
SerializationJSONState format

Session State Schema

FieldTypeDescription
session_idstringUnique identifier
user_idstringUser reference
created_attimestampSession start
last_activetimestampLast interaction
contextobjectAccumulated context
metadataobjectSession settings
•••

Long-Term Memory: Persistent Knowledge

What to Remember

CategoryExamplesValue
User preferencesTone, format, lengthPersonalization
User factsName, role, companyContext
Interaction historyPast questions, feedbackLearning
User documentsUploaded files, notesReference
Learned behaviorsCorrections, preferencesImprovement

Storage Architecture

LayerTechnologyData Type
RelationalPostgreSQLStructured facts
VectorPinecone/QdrantSemantic search
DocumentMongoDBFlexible objects
CacheRedisHot data

Memory Retrieval

TriggerWhat to RetrieveMethod
User identifiedUser preferencesDirect lookup
Query receivedRelevant memoriesSemantic search
Context neededRelated interactionsHybrid search

Retrieval Pipeline

StepActionLatency
1Extract query entities10ms
2Fetch user profile20ms
3Semantic search memories50ms
4Rerank by relevance30ms
5Inject into context5ms
TotalEnd-to-end~115ms
•••

Memory Writing

When to Write

TriggerWhat to StorePriority
Explicit statement"My name is..."High
Inferred preferenceRepeated behaviorMedium
Task completionSummary, outcomeMedium
User feedbackCorrectionsHigh
Conversation endSession summaryLow

Memory Extraction

MethodAccuracyCostLatency
Rule-based60%Free5ms
NER extraction75%Low20ms
LLM extraction90%Medium300ms
Human review99%HighAsync

Memory Schema

FieldTypeDescription
memory_idstringUnique identifier
user_idstringOwner
typeenumfact, preference, event
contentstringMemory content
embeddingvectorSemantic representation
confidencefloatExtraction confidence
sourcestringWhere it came from
created_attimestampWhen stored
accessed_attimestampLast accessed
access_countintegerUsage frequency
•••

Memory Consolidation

The Consolidation Problem

ChallengeDescriptionSolution
RedundancySame fact stored multiple timesDeduplication
ContradictionConflicting memoriesRecency preference
StalenessOutdated informationTTL, versioning
NoiseLow-value memoriesImportance scoring

Consolidation Process

StepActionFrequency
1Identify duplicatesDaily
2Merge similar memoriesDaily
3Resolve contradictionsOn access
4Prune low-valueWeekly
5Update embeddingsMonthly

Importance Scoring

FactorWeightReasoning
Access frequency30%Used memories are valuable
Recency25%Recent is relevant
Explicit statement25%User told us directly
Source quality20%Some sources more reliable
•••

Memory Privacy Levels

LevelDescriptionUser Control
EphemeralNot storedDefault
SessionStored for sessionOpt-in
PersistentStored long-termExplicit consent
SharedAcross contextsSeparate consent

User Controls

ControlImplementationUI Element
View memoriesDisplay stored dataMemory viewer
Delete memoryRemove specificDelete button
Clear allWipe user dataSettings
ExportDownload dataExport button
PauseStop storingToggle

Compliance Requirements

RequirementImplementation
Right to accessMemory viewer
Right to deletionDelete functionality
Right to portabilityExport feature
ConsentExplicit opt-in
MinimizationOnly store necessary
•••

Evaluation Metrics

Memory Quality

MetricDescriptionTarget
Recall accuracyCorrect memories retrievedOver 90%
PrecisionRelevant memories retrievedOver 80%
Extraction accuracyCorrect memory storedOver 85%
FreshnessUp-to-date informationOver 95%

User Experience

MetricDescriptionTarget
Personalization scoreUser-rated relevanceOver 4/5
Context continuitySeamless sessionsOver 90%
Memory latencyRetrieval timeUnder 200ms
False memoriesIncorrect recallsUnder 2%
•••

Architecture Patterns

Simple Memory (MVP)

ComponentImplementation
WorkingFull conversation in context
Short-termRedis session store
Long-termPostgreSQL user table

Advanced Memory

ComponentImplementation
WorkingSummarization + recent
Short-termRedis with state machine
Long-termVector DB + relational
ConsolidationBackground jobs
Diagram
flowchart TB subgraph Working["Working Memory"] W1[Current Message] W2[Recent Context] W3[Active Goals] end subgraph ShortTerm["Short-Term Memory"] S1[Session State] S2[Conversation History] S3[Temporary Facts] end subgraph LongTerm["Long-Term Memory"] L1[User Profile] L2[Semantic Facts] L3[Episodic Memories] end W1 --> S2 S2 --> |Consolidation| L3 S3 --> |Extraction| L2 L1 --> W2 L2 --> W2 L3 --> W2 style Working fill:#22c55e,color:#fff style ShortTerm fill:#f59e0b,color:#fff style LongTerm fill:#3b82f6,color:#fff
Python
from dataclasses import dataclass
from typing import List, Optional
from datetime import datetime

@dataclass
class Memory:
    content: str
    memory_type: str  # "fact", "episode", "preference"
    importance: float  # 0-1
    created_at: datetime
    last_accessed: datetime
    access_count: int

class MemorySystem:
    def __init__(self, redis, vector_db, postgres):
        self.working = WorkingMemory(max_tokens=4000)
        self.short_term = ShortTermMemory(redis, ttl_hours=24)
        self.long_term = LongTermMemory(vector_db, postgres)
    
    async def remember(self, user_id: str, content: str, memory_type: str):
        """Store a new memory with appropriate importance scoring."""
        
        # Calculate importance based on content analysis
        importance = await self._calculate_importance(content, memory_type)
        
        memory = Memory(
            content=content,
            memory_type=memory_type,
            importance=importance,
            created_at=datetime.now(),
            last_accessed=datetime.now(),
            access_count=0
        )
        
        # Store in appropriate layer based on importance
        if importance > 0.8:
            await self.long_term.store(user_id, memory)
        else:
            await self.short_term.store(user_id, memory)
    
    async def recall(self, user_id: str, query: str, k: int = 5) -> List[Memory]:
        """Retrieve relevant memories for the current context."""
        
        # Get from all layers
        working_context = self.working.get_context()
        short_term = await self.short_term.search(user_id, query, k=k)
        long_term = await self.long_term.search(user_id, query, k=k)
        
        # Combine and rank by relevance + recency + importance
        all_memories = short_term + long_term
        ranked = self._rank_memories(all_memories, query)
        
        # Update access patterns
        for memory in ranked[:k]:
            memory.last_accessed = datetime.now()
            memory.access_count += 1
        
        return ranked[:k]
    
    async def consolidate(self, user_id: str):
        """Background job: promote important short-term to long-term."""
        
        # Find frequently accessed short-term memories
        candidates = await self.short_term.get_high_access(user_id, min_count=3)
        
        for memory in candidates:
            # Extract durable facts
            facts = await self._extract_facts(memory.content)
            for fact in facts:
                await self.long_term.store(user_id, Memory(
                    content=fact,
                    memory_type="fact",
                    importance=memory.importance,
                    created_at=datetime.now(),
                    last_accessed=datetime.now(),
                    access_count=0
                ))
            
            # Remove from short-term
            await self.short_term.delete(user_id, memory.id)
    
    def _rank_memories(self, memories: List[Memory], query: str) -> List[Memory]:
        """Rank memories by composite score."""
        
        def score(m: Memory) -> float:
            # Recency decay
            age_hours = (datetime.now() - m.last_accessed).total_seconds() / 3600
            recency = 1 / (1 + age_hours / 24)
            
            # Combine factors
            return (
                0.4 * m.importance +
                0.3 * recency +
                0.2 * min(m.access_count / 10, 1) +
                0.1 * self._semantic_similarity(m.content, query)
            )
        
        return sorted(memories, key=score, reverse=True)

Enterprise Memory

ComponentImplementation
WorkingAdaptive context management
Short-termDistributed cache
Long-termMulti-modal memory graph
ConsolidationML-based importance
PrivacyFull compliance suite
•••

Key Takeaways

  1. 1Memory is not one thing - Working, short-term, and long-term memory serve different purposes and need different architectures.
  1. 2Retrieval is as important as storage - Fast, relevant memory retrieval is what makes memory useful.
  1. 3Write selectively - Not everything should be remembered. Store what matters, with appropriate confidence.
  1. 4Consolidate regularly - Memories need maintenance. Deduplicate, resolve conflicts, and prune.
  1. 5Privacy is non-negotiable - Users must control their data. Build consent and deletion into the architecture.
  1. 6Start simple - Begin with session memory, add long-term when you have proven value.

Memory transforms AI from a tool into a relationship. Build it thoughtfully, and your users will never want to go back to stateless interactions.

Found this helpful?

Share it with others who might benefit

TweetShare

Related articles