Blog/LangChain Persistent Memory
Tutorial · 5 min read

How to Add Persistent Memory to Any LangChain Agent (5-Minute Integration)

LangChain agents are powerful — but they forget everything the moment a session ends. Every new conversation starts from scratch. Here's how to fix that in under 5 minutes.

Synap Team·

The Problem: Your LangChain Agent Has Amnesia

You've built a LangChain agent. It's smart, it reasons well, and users love it — until they close the tab and come back tomorrow. Suddenly, the agent has no idea who they are, what they've discussed, or what preferences they've set.

This isn't a LangChain bug. It's a fundamental property of LLMs: they're stateless. Every API call is a fresh slate. LangChain's built-in ConversationBufferMemory helps within a session, but the moment your Python process restarts or a user opens a new browser tab, all context is gone.

The result? Users repeat themselves constantly. Customer support agents ask for order numbers they already have. Personal assistants forget stated preferences. Coding assistants re-learn your project conventions on every session. This is a terrible user experience — and it's completely solvable.

The Naive Approach: Storing History in a Dict

Most developers try to solve this with a simple dictionary or database table:

python
# The naive approach — looks simple, breaks fast
user_sessions = {}

def get_agent_response(user_id: str, message: str):
    history = user_sessions.get(user_id, [])
    history.append({"role": "user", "content": message})

    # Dump the entire history into the context window
    context = "\n".join([f"{m['role']}: {m['content']}" for m in history])
    response = agent.run(f"{context}\n{message}")

    history.append({"role": "assistant", "content": response})
    user_sessions[user_id] = history
    return response

This works for the first few messages. Then the problems start:

  • Context window overflow. After 20+ messages, you hit token limits. You start truncating history, which means the agent forgets older context.
  • No semantic retrieval. You're injecting everything, relevant or not. A user asking about shipping shouldn't get context from a 3-month-old conversation about returns.
  • Process restarts wipe state. That dict lives in RAM. Deploy a new version, restart the server, or scale to multiple instances — memory is gone.
  • No cross-agent sharing. If you run multiple agents (support + sales + onboarding), each starts from zero for the same user.

You can patch these problems one by one — add a database, add a vector store, add compression logic. Or you can use an API that already handles all of this.

The Synap Approach: 3 Lines of Code

Synap is a memory API built specifically for AI agents. It handles persistence, semantic retrieval, context compression, and cross-session continuity — so you don't have to.

Here's the difference in practice:

python
# Without Synap — agents forget everything
agent.run("What was my last order?")  # Agent has no idea

# With Synap — persistent memory across sessions
from synap import SynapClient

client = SynapClient(api_key="syn_your_key")
client.remember(user_id, "Last order: MacBook Pro, Jan 15")
memory = client.recall(user_id)
agent.run(f"Context: {memory}\nWhat was my last order?")  # Agent remembers!

Three methods. That's the entire API surface for the core use case:

  • remember(user_id, content)— Stores a memory, encoded as a semantic vector
  • recall(user_id, query?)— Retrieves relevant memories using semantic search
  • compress(user_id, context)— Compresses long context into a concise summary

Under the hood, Synap uses a semantic encoder to embed memories as vectors, a relevance scorer to surface the most important context for each query, and a forgetting curve to gracefully decay stale memories — just like human memory.

Real-World Example: A Customer Support Agent That Actually Remembers

Let's build a concrete example: a customer support agent that remembers user preferences, past orders, and prior issues across sessions.

Installation

bash
pip install synap-memory langchain langchain-openai

Basic Setup

python
from langchain.agents import AgentExecutor, create_openai_functions_agent
from langchain_openai import ChatOpenAI
from langchain.tools import tool
from synap import SynapClient

client = SynapClient(api_key="syn_your_key")
llm = ChatOpenAI(model="gpt-4o", temperature=0)

@tool
def lookup_order(order_id: str) -> str:
    """Look up order details by order ID."""
    # Your order lookup logic here
    return f"Order {order_id}: MacBook Pro 14\", shipped Jan 15, delivered Jan 17"

The Memory-Aware Agent

python
def handle_support_message(user_id: str, message: str) -> str:
    # 1. Recall relevant memories for this user
    memories = client.recall(user_id, query=message)

    # 2. Build context-aware system prompt
    system_prompt = f"""You are a helpful customer support agent.

User context from previous sessions:
{memories if memories else "No previous context for this user."}

Use this context to provide personalized support. Don't ask for information
the user has already provided in past sessions."""

    # 3. Run the agent with injected memory
    agent = create_openai_functions_agent(llm, [lookup_order], system_prompt)
    executor = AgentExecutor(agent=agent, tools=[lookup_order])
    response = executor.invoke({"input": message})["output"]

    # 4. Remember this interaction for future sessions
    client.remember(user_id, f"User asked: {message[:200]}. Agent responded: {response[:200]}")

    return response


# Session 1 — User provides context
handle_support_message("user_123", "Hi! I prefer email updates, not SMS.")
handle_support_message("user_123", "My email is alice@example.com")
handle_support_message("user_123", "I just placed order #A8821 for a laptop.")

# --- Days later, new session ---

# Session 2 — Agent already knows the user
response = handle_support_message("user_123", "Where's my laptop?")
# Agent knows: email preference, email address, order #A8821
# No re-explaining needed. Pure continuity.
print(response)

Native LangChain Memory Integration

Prefer the native LangChain memory interface? Synap ships a SynapMemory class that extends BaseChatMemory:

python
from synap.langchain import SynapMemory
from langchain.chains import ConversationChain

# Drop-in replacement for ConversationBufferMemory
memory = SynapMemory(api_key="syn_your_key", agent_id="support-agent-user_123")

chain = ConversationChain(llm=llm, memory=memory)

# Session 1
chain.predict(input="I prefer email updates over SMS.")

# Restart your server, start a new process...

# Session 2 — memory is loaded from Synap automatically
chain.predict(input="How do you normally contact me?")
# > "Based on your preference, I'd use email to contact you."

What just happened? Synap automatically compressed older conversation turns, stored them as semantic vectors, and retrieved the relevant ones when the new session started. You got cross-session continuity with zero extra infrastructure.

Why Not Just Use LangChain's Built-In Memory?

FeatureLangChain Built-inSynap
Cross-session persistence❌ RAM only✅ Durable
Semantic retrieval❌ Full history dump✅ Query-aware recall
Auto context compression❌ Manual✅ Automatic
Multi-agent sharing❌ Per-chain✅ Shared by user_id
Forgetting curve❌ None✅ Decay over time
Scale to millions of users❌ Memory pressure✅ Distributed

Performance: <10ms Latency

Memory retrieval adds less than 10ms (p99) to your agent's response time. Synap runs Redis-backed caching with a pgvector index for semantic search — so recall() returns in a single round-trip, not a multi-step pipeline. For most agents, this is imperceptible to end users.

Live API · Ready now

Give Your Agents a Memory Layer Today

Synap Memory API gives your LangChain agents persistent memory, semantic recall, and automatic context compression. One API call. No infrastructure to manage.

Includes 1M memory operations/month · Python SDK · 365-day retention · 30-day money-back guarantee