How to Configure AI Agent Memory in Dify: A Complete Guide
How to Configure AI Agent Memory in Dify: A Complete Guide
Marvel Ken
March 2, 2026
AI agents are technically stateless by default; by this, it means every time a user sends a message, the underlying language model has no memory of what was actually said prior. Without a memory configuration, your chatbot forgets the user's name between messages, loses track of the problem they're trying to solve, and will end up asking the same clarifying questions repeatedly.
Dify agent memory solves this. It determines how your AI agents retain context across conversations, letting them reference past interactions and store user preferences, without losing track of what's already been discussed.
In this article, we will walk you through Dify's memory system from the ground up. You'll learn what memory types are available, how to configure them step-by-step, and how to test if everything works via the API.
TL;DR: Dify Agent Memory Configuration
- AI agents are stateless by default, and memory configuration gives them context across conversations
- Dify offers two main memory types: Conversational (short-term) via TokenBufferMemory, and Long-term via Knowledge Base + vector databases
- Enable memory by toggling it on in your Agent node, then set a Window Size (50–100 is a good starting point)
- Always pass
conversation_idin API calls to maintain continuity across messages - Use Conversation Variables when you need structured, persistent data storage
- For a simpler setup, the plugin handles memory externally without manual wiring
What Is AI Agent Memory in Dify?
Agent memory in Dify is a layer responsible for managing conversation context independently from raw LLM context windows. When you enable memory on an Agent node, Dify uses TokenBufferMemory to buffer recent conversation messages up to a configurable limit, then automatically add this history to each LLM call.
This differs from simply passing chat history to an LLM. Dify's memory system handles token counting, message truncation, and context formatting. You configure the window size, and Dify manages the rest. The backend was built to enforce hard limits (2000 tokens, 500 messages maximum) regardless of your settings, preventing runaway costs while maintaining conversational fluency.
Why Does Memory Configuration Matter?
LLMs are stateless by default. Each API call starts fresh with no knowledge of previous interactions. Without memory configuration, a customer support bot would forget the user's issue mid-conversation, and a personal assistant can't remember preferences mentioned five messages ago.
The impact is measurable. When users reference previous context ("as I mentioned earlier," "the file I uploaded," "my budget from before"), agents without properly configured memory fail to resolve these references. Users must repeat themselves, making the conversational flow stressful and reducing task completion rates.
The tradeoff: larger memory windows provide more context but increase token consumption linearly. A 100-message window on GPT-5.3 can cost 10x as much per response as a 10-message window. Configuration is about finding that balance where enough context for coherent conversations meets sustainable costs.
What Are Dify's Memory Types?
Dify offers a dual-system approach, providing both short-term, session-based memory for immediate context and long-term, persistent memory for knowledge and preferences. We will look at both of these essential memory types.
Conversational Memory (Short-Term)
Dify's built-in memory operates at the session level using TokenBufferMemory as mentioned earlier. Enable the Memory toggle on Agent or LLM nodes, set Window Size, and Dify automatically includes recent messages in each prompt.
memory_config = {
"type":"TokenBufferMemory",
"window_size":50, # Messages to include
"max_tokens":2000, # Hard backend limit
"max_messages":500 # Hard backend limit
}
This type of memory comes in handy in Multi-turn Q&A, customer support conversations, and any workflow where context from recent messages really matters.
They are not left with limitations, as the memory resets when conversations end. They have no persistence across sessions. No semantic filtering, all recent messages are included regardless of relevance.
Long-Term Memory (Persistent)
For memory that persists across sessions or requires semantic retrieval, Dify uses Knowledge Bases backed by vector databases. Store conversation history or extracted facts as documents, then retrieve relevant context using the Knowledge Retrieval node.
Dify supports 13+ vector databases through environment configuration:
# Self-hosted configuration (.env)
VECTOR_STORE=qdrant # Options: weaviate, qdrant, milvus, pgvector, tidb, etc.
QDRANT_URL=https://your-cluster.qdrant.tech/
QDRANT_API_KEY=your_api_key
Below are database best suited for each use case
| Database | Best For |
| Weaviate | Default in Docker, easy setup |
| Qdrant | Production performance, hybrid search |
| Milvus | Large-scale deployments |
| PGVector | Existing PostgreSQL infrastructure |
This kind of memory is useful for Preference retention across sessions, semantic memory search, and RAG-based context retrieval. Going further, we will see how we can configure this memory.
How Do You Configure Memory in Dify?
Memory configuration in Dify happens at two levels: basic toggles for quick setup, and advanced patterns using Conversation Variables for better control.
Basic Configuration
Now that you understand how Dify's memory system works under the hood, let's configure it. The setup takes just a few steps inside the Dify interface.
Step 1: Set Up Your Model Provider
Before configuring memory, you need a model provider connected. Navigate to Settings → Model Provider and configure your API credentials. For this article, we will be using OpenRouter, Gemini 2.5 flash:
Once configured, your model appears as available in the API Keys section.
Step 2: Create a Chatflow and Add an Agent Node
From the Studio, create a new Chatflow or just use what’s already provided. You can replace the LLM in the image below with an Agent node:
A Chatflow with START → LLM → ANSWER nodes, plus an Agent node. The Agent node requires configuration before use.
Step 3: Configure the Agent Strategy
Click on the Agent node and select an Agentic Strategy. Choose either Function Calling (for models like GPT-4, Claude, Gemini) or ReAct (for explicit reasoning traces). In this article, we used Function calling.
Agent node configured with Function Calling strategy, Gemini 2.5 Flash model, Code Interpreter tool, and custom instructions.
Step 4: Enable Memory and Set Window Size
To do this, you will need to scroll down in the Agent settings to find the Memory section under Execution Controls.
The Memory toggle (currently OFF) controls whether the Agent retains conversation context.
Toggle Memory ON, toggle Window size on, and adjust the Window Size slider:
Memory enabled with Window Size set to 50. This determines how many previous conversation turns the Agent can access.
The window size controls how many previous conversation turns the agent can access. The backend enforces hard limits: a maximum of 2000 tokens and up to 500 messages, regardless of your settings. Larger windows provide more context but increase token costs.
Step 5: Connect Query and Output
Configure the Query field to receive user input. Click the field and select the user input variable:
Agent fully configured with Query connected to User Input, Memory ON with Window Size 100, and Answer as the next step.
Step 6: Complete the Flow
Ensure your flow connects properly: START → AGENT → ANSWER
Complete Chatflow: User Input feeds into Agent 2, which outputs to the Answer node. The Agent shows the Function Calling strategy with the Gemini model.
Advanced Configuration: Conversation Variables
For structured data that persists across conversation turns, use Conversation Variables. To set this up, click the Variables icon (or find it in the top toolbar) to open the Conversation Variables panel:
The Conversation Variables panel shows how variables connect to your workflow. Variables are written via the Variable Assigner and read by LLM nodes.
Creating an Array[Object] Variable for Memory Storage
Click "+ Add Variable" to create a new Conversation Variable. For memory systems, use Array[object] type:
Creating a collected_memories variable with an Array[object] type. This allows storing structured memory objects that accumulate over time.
Supported data types include:
- string: Text values like language preferences
- number: Numeric values like counters
- boolean: True/false flags
- object: Structured data with nested properties
- array[string/number/boolean/object]: Collections for storing multiple items
And we are done with that.
API Access for Programmatic Control
For external integrations, Dify exposes a full API. Navigate to API Access in the left sidebar:
The API Access page shows the Base URL, authentication method, and available endpoints, including Send Chat Message, Get Conversation History, and Get Conversation Variables.
Getting Your API Key
Click to create and view your API Secret Key:
Your API Secret Key for authenticating requests. Store this securely and never expose it in client-side code.
Testing Memory via API
With your Chatflow published and API key ready, you can test memory functionality from your terminal.
Test 1: Start a Conversation
curl -X POST 'https://api.dify.ai/v1/chat-messages' \
--header 'Authorization: Bearer app-Y9wiahHbJiiNJBto05tx5Vno' \
--header 'Content-Type: application/json' \
--data '{
"inputs":{},
"query":"Hello, my name is Marvel, and I like Python",
"response_mode":"blocking",
"conversation_id":"",
"user":"test-user-123"
}'
Response:
{
"event":"message",
"conversation_id":"059503ea-bbdb-4ef0-a8fd-fae93ef645f1",
"answer":"Hello Marvel, it's great to meet you! Python is a fantastic language. Do you have any questions about it, or perhaps something you'd like to code?",
"metadata":{
"usage":{
"prompt_tokens":158,
"completion_tokens":35,
"total_tokens":193
}
}
}
The response includes a conversation_id - this is the key to maintaining memory across messages.
Test 2: Verify Memory Works
Use the same conversation_id to continue the conversation and test if the Agent remembers context:
curl -X POST 'https://api.dify.ai/v1/chat-messages' \
--header 'Authorization: Bearer app-Y9wiahHbJiiNJBto05tx5Vno' \
--header 'Content-Type: application/json' \
--data '{
"inputs":{},
"query":"What is my name?",
"response_mode":"blocking",
"conversation_id":"059503ea-bbdb-4ef0-a8fd-fae93ef645f1",
"user":"test-user-123"
}'
Response:
{
"event":"message",
"conversation_id":"059503ea-bbdb-4ef0-a8fd-fae93ef645f1",
"answer":"Your name is Marvel.",
"metadata":{
"usage":{
"prompt_tokens":200,
"completion_tokens":51,
"total_tokens":251
}
}
}
The Agent correctly remembered the name "Marvel" from the previous message, proving that memory configuration is working correctly.
Test 3: Retrieve Conversation History
You can also retrieve the full conversation history via API:
curl -X GET 'https://api.dify.ai/v1/messages?conversation_id=059503ea-bbdb-4ef0-a8fd-fae93ef645f1&user=test-user-123&limit=20' \
--header 'Authorization: Bearer app-YOUR_KEY_HERE'
Response:
{
"limit":20,
"has_more":false,
"data":[
{
"id":"06b4bf76-8933-40b7-8a24-3ab68d9055bd",
"conversation_id":"059503ea-bbdb-4ef0-a8fd-fae93ef645f1",
"parent_message_id":"00000000-0000-0000-0000-000000000000",
"inputs":{},
"query":"Hello, my name is Marvel, and I like Python",
"answer":"Hello Marvel, it's great to meet you! Python is a fantastic language. Do you have any questions about it, or perhaps something you'd like to code?",
"feedback":null,
"retriever_resources":[],
"created_at":1771405015,
"agent_thoughts":[],
"message_files":[],
"status":"normal",
"error":null
},
{
"id":"03925e05-9486-4aa9-b06e-795621a9cb49",
"conversation_id":"059503ea-bbdb-4ef0-a8fd-fae93ef645f1",
"parent_message_id":"00000000-0000-0000-0000-000000000000",
"inputs":{},
"query":"What is my name?",
"answer":"Your name is Marvel.",
"feedback":null,
"retriever_resources":[],
"created_at":1771405062,
"agent_thoughts":[],
"message_files":[],
"status":"normal",
"error":null
}
]
}
The response returns an array of messages ordered chronologically. Each message includes the query (user input), answer (agent response), timestamps, and metadata like retriever_resources for RAG applications and agent_thoughts for reasoning traces.
Variable Assigner for Custom Memory
Use Variable Assigner nodes to write to Conversation Variables. Set operation to Append for arrays that accumulate memories across turns. For a complete OpenAI-style memory pattern, see: Dify's Official Tutorial.
Key Takeaways
- Memory Toggle: Enable in the Agent node's Execution Controls section.
- Window Size: Controls context depth (backend limits: 2000 tokens, 500 messages max).
- Conversation Variables: Use for structured data storage with types like
Array[object]. - conversation_id: The critical parameter for maintaining memory across API calls.
- Variable Assigner: Writes data to Conversation Variables using operations like append, overwrite, and clear.
Memory configuration transforms stateless LLM calls into contextual conversations. You can start with the basic Memory toggle for simple use cases, then add Conversation Variables when you need structured, persistent data storage.