3
Memory: Agents That Remember

Learn how to give your agents memory to maintain context across conversations

Watch This Step Video

The Problem: Agents with Amnesia

Your agent can use tools, but every conversation starts from scratch. It can't remember previous interactions, learn from past conversations, or build context over time.

Without Memory

Asks for the same information repeatedly
Can't build on previous conversations
No user preferences or context

With Memory

Remembers user details and preferences
Builds context across conversations
Learns from interactions

Types of Agent Memory

Different types of memory serve different purposes. Let's understand what each one does:

Automatic Memory (Zero Configuration)

Memory is enabled by default when you create an agent
Creates .voltagent/memory.db file in your project
Conversation history is automatically saved
!Requires userId to function properly

Critical: userId Required for Memory

Without a userId, your agent can't properly isolate and store conversations. This is the most common reason why memory "doesn't work" in VoltAgent.

Memory in Action: Test Your Agent

Run your weather agent and test memory functionality. The key is setting a userId - without it, memory won't work properly.

Testing with VoltOps Console

2.Click the Settings icon (gear) in the chat interface
3.Set userId to something like "sarah-123"
4.Set conversationId to "test-memory"
5.Now test the conversation below!

See Memory in Action

This demo shows how memory works with proper userId and conversationId settings in VoltOps:

VoltOps Memory Demo - Agent remembering user information

Memory working: Agent remembers the user's name across messages

Test Scenario (with userId set)

1st Message: "Hi, my name is Sarah."
Agent: "Hello Sarah! How can I help you?"
2nd Message: "What's the weather in London today?"
Agent: "Checking London weather for you..."
3rd Message: "What's my name again?"
Agent (with memory): "Your name is Sarah!"

The Power of Proper Memory Setup!

With the correct userId and conversationId, your agent now remembers previous conversations and provides a natural, contextual experience. This transforms user experience from robotic to human-like.

User and Conversation IDs

In real applications, you have multiple users and conversations. VoltAgent uses userId and conversationId to keep them separate. userId is mandatory for proper memory functionality.

userId

Unique identifier for each user
Users can't see each other's conversations
Example: "user-123", "[email protected]"

conversationId

Unique identifier for each conversation thread
Users can have multiple conversations
Example: "support-case-456", "chat-xyz"
How to Use Memory Properly - userId is Required
// ❌ WITHOUT userId - Memory won't work properly
const badResponse = await agent.generateText("Hi, my name is Alice.");
// Uses default userId, memory isolation fails

// ✅ WITH userId - Memory works correctly
const response1 = await agent.generateText("Hi, my name is Alice.", {
userId: "alice-123", // REQUIRED for memory to work
conversationId: "chat-session-1" // Optional but recommended
});

const response2 = await agent.generateText("What's my name?", {
userId: "alice-123", // SAME userId = access to memory
conversationId: "chat-session-1" // SAME conversation = full context
});
// Agent: "Your name is Alice!" ✅ Memory working!

// Different user = isolated memory
const response3 = await agent.generateText("Hello, I'm Bob.", {
userId: "bob-456", // DIFFERENT userId = separate memory
conversationId: "chat-session-2"
});

// Same user, new conversation = fresh start but same user profile
const response4 = await agent.generateText("Let's talk about something new.", {
userId: "alice-123", // SAME user
conversationId: "new-topic" // NEW conversation = fresh context
});

Memory Options

VoltAgent offers different memory types. Choose the one that fits your needs.

LibSQLStorage (Default)

Used automatically
Local SQLite file
Turso support
Perfect for development

InMemoryStorage

Very fast
Ideal for testing and development
!Data lost when app restarts

PostgreSQL

Enterprise-grade
Complex queries
Perfect for production

Supabase

Cloud-based
Easy setup
Auto-scaling

Custom Memory Options

If the default memory isn't enough, you can create your own memory provider.

Disabling Memory
// Completely disable memory
const statelessAgent = new Agent({
name: "Stateless Agent",
instructions: "This agent remembers nothing.",
llm: new VercelAIProvider(),
model: openai("gpt-4o-mini"),
memory: false // Memory disabled
});
Using InMemory Storage
import { InMemoryStorage } from "@voltagent/core";

const fastAgent = new Agent({
name: "Fast Agent",
instructions: "This agent stores memory in RAM.",
llm: new VercelAIProvider(),
model: openai("gpt-4o-mini"),
memory: new InMemoryStorage()
});
PostgreSQL Memory
import { PostgreSQLStorage } from "@voltagent/postgres";

const productionAgent = new Agent({
name: "Production Agent",
instructions: "This agent stores memory in PostgreSQL.",
llm: new VercelAIProvider(),
model: openai("gpt-4o-mini"),
memory: new PostgreSQLStorage({
connectionString: process.env.DATABASE_URL
})
});

Best Practices

Follow these tips to use memory effectively.

Do This

Always use userId and conversationId
Consider user privacy
Use PostgreSQL/Supabase in production
Use InMemory for testing

Don't Do This

Don't ignore memory limits
Don't log sensitive information
Don't forget to handle memory errors
Don't use InMemory in production

Using Memory via REST API

If you're building a web app or mobile app, you'll likely call your VoltAgent via REST API. Here's how to properly set userId and conversationId in API calls.

API Server URL

Your VoltAgent automatically starts an API server on port 3141 (or another available port):

✓ HTTP Server: http://localhost:3141
✓ Swagger UI: http://localhost:3141/ui
Basic API Call (Without Memory - Don't Do This)
# ❌ Without userId - Memory won't work
curl -X POST http://localhost:3141/agents/my-agent/text \
-H "Content-Type: application/json" \
-d '{
"input": "Hi, my name is Sarah. What's the weather like?"
}'
Proper API Call (With Memory - Do This)
# ✅ With userId and conversationId - Memory works!
curl -X POST http://localhost:3141/agents/my-agent/text \
-H "Content-Type: application/json" \
-d '{
"input": "Hi, my name is Sarah. What\'s the weather like?",
"options": {
"userId": "sarah-123",
"conversationId": "weather-chat-001"
}
}'

# Follow-up message in same conversation
curl -X POST http://localhost:3141/agents/my-agent/text \
-H "Content-Type: application/json" \
-d '{
"input": "What was my name again?",
"options": {
"userId": "sarah-123",
"conversationId": "weather-chat-001"
}
}'
# Response: "Your name is Sarah!" ✅
JavaScript/TypeScript Example
// Frontend code example
const userId = getCurrentUserId(); // Get from your auth system
const conversationId = generateConversationId(); // Generate or get existing

async function chatWithAgent(message) {
const response = await fetch('http://localhost:3141/agents/my-agent/text', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
input: message,
options: {
userId: userId, // REQUIRED for memory
conversationId: conversationId, // Optional but recommended
temperature: 0.7,
maxTokens: 500
}
})
});

const result = await response.json();
return result.data;
}

// Usage
await chatWithAgent("Hi, I'm Sarah. What's the weather?");
await chatWithAgent("What's my name?"); // Will remember "Sarah"

Key Points for API Usage

1.Always include userId in the options object
2.Use the same userId for the same user across all requests
3.Use the same conversationId to maintain conversation context
4.Generate new conversationId for new conversation threads
5.Check http://localhost:3141/ui for interactive API docs