Agno agents forget everything by default. Here is how to add session memory, user memory, and persistent storage.

The Default Behaviour

Agno agents are stateless by default. Every new run starts fresh: the agent has no memory of previous conversations, no knowledge of user preferences, and no persistent state. This is fine for one-shot tasks. For any conversational or long-running use case, you need to configure memory explicitly.

Agno has three distinct memory systems, each serving a different purpose. Understanding which one to use -- and when -- is the gap this article fills.

The Three Memory Types

Memory Type What it stores Scope Persists?
Session Storage Full conversation history for one session Per session Only with a DB backend
User Memory Facts about a specific user across sessions Per user (cross-session) Yes, requires DB
Agent Memory (Knowledge) Fixed reference knowledge the agent always has Global (all users) Yes, vector store

Session Memory: Remembering the Conversation

Session memory stores the full message history for a conversation. Without it, the agent cannot refer back to anything said earlier in the same chat.

from agno.agent import Agent
from agno.models.anthropic import Claude
from agno.storage.postgres import PostgresStorage
 
# In-memory session storage (development only -- lost on restart)
agent = Agent(
    model=Claude(id="claude-sonnet-4-6"),
    add_history_to_messages=True,   # inject conversation history into each prompt
    num_history_responses=10,       # how many past exchanges to include
)
 
# Persistent session storage with PostgreSQL (production)
agent = Agent(
    model=Claude(id="claude-sonnet-4-6"),
    storage=PostgresStorage(
        table_name="agent_sessions",
        db_url="postgresql://user:pass@host/dbname",
    ),
    add_history_to_messages=True,
    num_history_responses=10,
)
 
# Use session_id to link messages across requests
result = await agent.arun(
    "What is the capital of France?",
    session_id="user-123-session-456",
)
result2 = await agent.arun(
    "And what language do they speak there?",  # agent remembers France was mentioned
    session_id="user-123-session-456",         # same session_id = same conversation
)
Always pass an explicit session_id. Without one, Agno generates a random UUID per run, which means every message starts a new conversation. Store the session_id in your application's session store (cookie, JWT, Redis) and pass it back with every request.

User Memory: Remembering Facts Across Sessions

User memory stores facts about a specific user that should persist across multiple conversations. The agent can read these facts at the start of any session and update them during a conversation.

from agno.memory.db.postgres import PostgresMemoryDb
from agno.memory.agent import AgentMemory
 
agent = Agent(
    model=Claude(id="claude-sonnet-4-6"),
    memory=AgentMemory(
        db=PostgresMemoryDb(
            table_name="user_memories",
            db_url="postgresql://user:pass@host/dbname",
        ),
        create_user_memories=True,   # agent saves facts it learns about the user
        update_user_memories=True,   # agent updates facts when they change
    ),
    add_history_to_messages=True,
    storage=PostgresStorage(
        table_name="agent_sessions",
        db_url="postgresql://user:pass@host/dbname",
    ),
)
 
# Session 1 -- agent learns the user's name and preferences
result = await agent.arun(
    "Hi, I'm Sarah. I prefer concise answers and I work in healthcare.",
    user_id="user-sarah-123",
    session_id="session-001",
)
 
# Session 2 (days later) -- agent remembers Sarah
result = await agent.arun(
    "Can you help me with a patient data workflow?",
    user_id="user-sarah-123",   # same user_id links to stored memories
    session_id="session-002",   # new session, but user memory persists
)
# Agent knows: user is Sarah, prefers concise answers, works in healthcare

Agent Knowledge: Always-Available Reference Data

Agent knowledge (also called agent memory in some Agno versions) is a vector store containing reference documents that the agent always has access to. This is different from user memory -- it is the same for all users and represents the agent's domain expertise.

from agno.agent import Agent
from agno.knowledge.pdf import PDFKnowledgeBase
from agno.vectordb.postgres import PgVector
 
agent = Agent(
    model=Claude(id="claude-sonnet-4-6"),
    knowledge=PDFKnowledgeBase(
        path="./knowledge-docs/",           # folder of PDFs to index
        vector_db=PgVector(
            table_name="agent_knowledge",
            db_url="postgresql://user:pass@host/dbname",
        ),
    ),
    search_knowledge=True,   # agent automatically searches knowledge on each run
)
 
# Load the knowledge base (run once, or on updates)
await agent.knowledge.aload()
 
result = await agent.arun("What is our refund policy?")
# Agent searches the PDFs and answers from the indexed content

Full Production Setup

agent = Agent(
    model=Claude(id="claude-sonnet-4-6"),
    # Session history
    storage=PostgresStorage(
        table_name="agent_sessions",
        db_url=DB_URL,
    ),
    add_history_to_messages=True,
    num_history_responses=8,
    # User memory
    memory=AgentMemory(
        db=PostgresMemoryDb(table_name="user_memories", db_url=DB_URL),
        create_user_memories=True,
        update_user_memories=True,
    ),
    # Agent knowledge
    knowledge=PDFKnowledgeBase(
        path="./knowledge/",
        vector_db=PgVector(table_name="agent_knowledge", db_url=DB_URL),
    ),
    search_knowledge=True,
)

Quick Reference

  • Session storage: conversation history within one session -- use PostgresStorage
  • User memory: facts about a user across all sessions -- use AgentMemory + PostgresMemoryDb
  • Agent knowledge: reference documents for all users -- use PDFKnowledgeBase + PgVector
  • Always pass explicit session_id and user_id -- never rely on auto-generated IDs in production
  • Call knowledge.aload() once after indexing new documents
  • num_history_responses controls token cost -- start at 8-10 and tune from there