How to Fix 'memory not persisting during development' in AutoGen (TypeScript)
When AutoGen memory “doesn’t persist during development,” it usually means your agent state is being recreated on every reload, request, or process restart. In TypeScript, this shows up when you expect Memory, ChatMessageMemory, or a custom store to survive hot reloads, but the app is actually rebuilding the agent graph from scratch.
The symptom is simple: the first turn works, then the next run behaves like a brand-new agent. You’ll often see logs like No memory found for conversationId ... or memory length = 0 after a reload, even though you just added messages.
The Most Common Cause
The #1 cause is instantiating memory inside a request handler or component render, instead of creating one long-lived instance and reusing it.
This is especially common in Next.js API routes, serverless handlers, Vite dev servers, and any TypeScript app with hot module replacement. Every refresh creates a new Memory object, so nothing persists.
Broken vs fixed
| Broken pattern | Fixed pattern |
|---|---|
| Memory is created per request | Memory is created once and reused |
| State dies on reload | State survives within the process |
| Works once, then resets | Stable across multiple calls |
// broken.ts
import { AssistantAgent } from "@autogen/agents";
import { Memory } from "@autogen/memory";
export async function POST(req: Request) {
const memory = new Memory(); // recreated every request
const agent = new AssistantAgent({
name: "support-agent",
modelClient,
memory,
});
await memory.add({ role: "user", content: "My policy number is 12345" });
const result = await agent.run("What is my policy number?");
return Response.json(result);
}
// fixed.ts
import { AssistantAgent } from "@autogen/agents";
import { Memory } from "@autogen/memory";
const memory = new Memory(); // module-level singleton
const agent = new AssistantAgent({
name: "support-agent",
modelClient,
memory,
});
export async function POST(req: Request) {
const { message } = await req.json();
await memory.add({ role: "user", content: message });
const result = await agent.run("What did I just say?");
return Response.json(result);
}
If you’re using AutoGen’s newer agent abstractions, the same rule applies to Memory, ChatMessageMemory, and any storage-backed implementation. The object that owns state must outlive the request.
Other Possible Causes
1) You’re using in-memory storage in a dev server that restarts often
If your store is backed by process memory only, hot reload wipes it.
// ephemeral store
const memory = new Memory({
storage: "in-memory",
});
Use durable storage for anything you want to keep between reloads:
const memory = new Memory({
storage: {
type: "sqlite",
path: "./data/autogen.db",
},
});
2) Your conversation ID changes every run
AutoGen can only retrieve prior context if you reuse the same thread or conversation identifier.
// broken: random id each time
const conversationId = crypto.randomUUID();
Fix it by binding memory to a stable key:
// fixed: stable per user/session
const conversationId = `user:${userId}`;
If you’re storing chat history manually, make sure every read/write uses the same key.
3) You forgot to persist after mutation
Some implementations require an explicit save step. Adding messages to an object in memory does not always flush them to disk or DB.
await memory.add({ role: "assistant", content: "Noted." });
// missing await memory.save() or equivalent persistence call
Check your specific implementation for methods like:
- •
save() - •
commit() - •
flush() - •
close()
A common failure mode is assuming mutation equals persistence. It doesn’t.
4) Hot module replacement is duplicating singletons
In dev mode, bundlers can reload modules and create duplicate instances even if your code looks correct.
let memory = new Memory(); // re-executed on HMR
Guard it with a global cache:
declare global {
// eslint-disable-next-line no-var
var autogenMemory: Memory | undefined;
}
export const memory =
globalThis.autogenMemory ??= new Memory({
storage: { type: "sqlite", path: "./data/autogen.db" },
});
That pattern keeps one instance alive across local reloads in Node-based dev setups.
How to Debug It
- •
Log the instance identity
- •Print something stable like
memory.id,conversationId, or object reference info. - •If it changes after every request, you found the issue.
- •Print something stable like
- •
Check where construction happens
- •Search for
new Memory(,new AssistantAgent(, and any store initialization. - •If they live inside handlers, React components, or route functions, move them out.
- •Search for
- •
Verify the backend store
- •Confirm whether you are using SQLite/Postgres/Redis vs pure process memory.
- •If it’s in-memory only, persistence will stop at process boundaries.
- •
Trace read/write keys
- •Log the exact key used when saving and loading:
console.log({ conversationId }); - •A mismatch like
user-123on write andsession-456on read will look like lost memory.
- •Log the exact key used when saving and loading:
Prevention
- •Create agents and memory stores at module scope or behind a singleton factory.
- •Use durable storage for anything beyond throwaway dev experiments.
- •Tie every conversation to a stable session/user key and keep that key consistent across requests.
- •In frameworks with HMR, add a global cache guard for dev-time singletons.
If you’re seeing memory not persisting during development, don’t start by blaming AutoGen itself. In TypeScript apps, this almost always comes down to lifecycle management: where the object lives, how it’s keyed, and whether your store survives reloads.
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