How to Fix 'memory not persisting in production' in AutoGen (Python)
What this error usually means
When people say “memory not persisting in production” in AutoGen, they usually mean one of two things: the agent seems to remember things during a single run, but forgets everything after restart, or the memory store works locally and disappears once deployed. In practice, this shows up when state is kept in-process instead of in a durable backend, or when the production runtime is stateless and your code assumes otherwise.
The most common symptom is that your agent logs look fine for one request, then on the next request you see empty context, missing chat history, or behavior like it’s starting from scratch. You may also see errors around missing persistence backends, for example FileNotFoundError, sqlite3.OperationalError, or AutoGen components like ChromaDBVectorMemory and MongoDBMemory being reinitialized on every request.
The Most Common Cause
The #1 cause is storing memory in an object that only lives for the lifetime of the Python process. This works in local dev because your script stays alive, but fails in production behind Gunicorn, Uvicorn workers, containers, serverless functions, or any setup where processes restart.
Broken vs fixed pattern
| Broken pattern | Fixed pattern |
|---|---|
| Memory created inside the request handler | Memory created once and backed by persistent storage |
| Uses ephemeral in-memory state | Uses SQLite, MongoDB, Redis, or vector DB |
| Rebuilds agent every call | Reuses durable memory store across calls |
# BROKEN: memory dies with the process/request
from autogen_agentchat.agents import AssistantAgent
from autogen_ext.memory import ListMemory # ephemeral
def handle_request(user_input: str):
memory = ListMemory()
agent = AssistantAgent(
name="support_agent",
model_client=model_client,
memory=memory,
)
return agent.run(task=user_input)
# FIXED: persistent memory backed by storage
from autogen_agentchat.agents import AssistantAgent
from autogen_ext.memory import ChromaDBVectorMemory
# create once at app startup
memory = ChromaDBVectorMemory(
collection_name="support_memory",
persist_directory="/var/lib/app/chroma", # mounted volume
)
agent = AssistantAgent(
name="support_agent",
model_client=model_client,
memory=memory,
)
def handle_request(user_input: str):
return agent.run(task=user_input)
If you are using AutoGen’s newer agent stack, the important part is the same: do not assume ListMemory, ad hoc Python lists, or per-request objects are durable. In production you want a real backend plus a stable path to it.
Other Possible Causes
1) Your container filesystem is ephemeral
If you use Chroma or SQLite without a mounted volume, persistence looks fine until the container restarts.
# docker-compose.yml
services:
app:
image: my-autogen-app
volumes:
- ./data:/var/lib/app # keep this mounted
Without that volume, files under /tmp or inside the container layer vanish on redeploy.
2) You are running multiple workers with isolated state
If each worker has its own local cache or file-backed memory path, requests bounce between workers and “forget” history.
gunicorn app:app --workers 4
That is fine only if all workers point to the same durable store:
memory = ChromaDBVectorMemory(
collection_name="support_memory",
persist_directory="/mnt/shared/chroma",
)
If each worker points at /tmp/chroma, you have four different memories.
3) You never call the persistence write path
Some AutoGen memory implementations need an explicit save/update step depending on how you wired them. If you only append to an object but never commit to storage, nothing survives restart.
# Example pattern: ensure writes hit durable storage
await memory.add("user said they prefer email notifications")
await memory.save() # if your implementation exposes a flush/save step
Check your specific memory class. The exact method name varies by version and backend.
4) You’re recreating the agent graph on every request
A common mistake is putting model client creation, tool registration, and memory construction inside a FastAPI endpoint.
@app.post("/chat")
async def chat(req: ChatRequest):
# bad: everything rebuilt per request
agent = AssistantAgent(...)
Move setup to application startup and keep only request-specific inputs inside the handler.
How to Debug It
- •
Print the concrete memory class at runtime
- •Confirm whether you are actually using
ListMemory,InMemory*, or a persistent backend. - •Add:
print(type(agent.memory))
- •Confirm whether you are actually using
- •
Check where data is stored
- •For SQLite:
print(os.path.abspath("memory.db")) - •For Chroma:
print(persist_directory) - •Make sure that path survives deploys and restarts.
- •For SQLite:
- •
Restart the service and inspect history
- •Run one conversation.
- •Restart the process/container.
- •Ask for prior context again.
- •If it disappears immediately after restart, you are still on ephemeral storage.
- •
Trace request lifecycle in logs
- •Log agent creation once at startup.
- •Log memory writes when messages are added.
- •If you see “created assistant agent” on every request, your architecture is wrong.
Prevention
- •Use a real persistence layer from day one: SQLite for small deployments, Postgres/MongoDB/Redis/Chroma for production-grade setups.
- •Initialize agents and memory at app startup, not inside request handlers.
- •In containers and Kubernetes, mount persistent volumes for any file-backed store.
- •Treat worker-local caches as disposable; never rely on them for user-facing memory.
If you’re seeing memory not persisting in production in AutoGen Python, assume it’s an architecture issue first. In almost every case I’ve seen, the fix is not “tune AutoGen,” it’s “stop storing state in process memory.”
Keep learning
- •The complete AI Agents Roadmap — my full 8-step breakdown
- •Free: The AI Agent Starter Kit — PDF checklist + starter code
- •Work with me — I build AI for banks and insurance companies
By Cyprian Aarons, AI Consultant at Topiax.
Want the complete 8-step roadmap?
Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.
Get the Starter Kit