1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
19 small wins to finish your pathNext lesson →
Store managers
A store manager is a memory manager joined to the LangGraph store: create_memory_store_manager searches a namespace for related memories, asks the model to extract and update, and writes the result back, in one call.
Last updated: 30 Sep, 2026 · LangMem 0.0.30
With a plain manager, your code passed existing in and saved the result out. The store manager does both itself. It also fills the namespace from the call's config, so one manager serves every customer and each customer's memories stay in their own namespace.
Syntax:
manager = create_memory_store_manager(model, namespace=("memories", "{user_id}"), store=store)
manager.invoke({"messages": conversation}, config={"configurable": {"user_id": "asha"}})A namespace template
"{user_id}" is replaced on every call with config["configurable"]["user_id"]. Without a namespace, LangMem uses ("memories", "{langgraph_user_id}").
manager = create_memory_store_manager(
model,
namespace=("memories", "{user_id}"),
instructions="Extract what helps support this customer. Record everything in a single Memory call.",
store=store,
)One config per customer
asha = {"configurable": {"user_id": "asha"}}
manager.invoke({"messages": [{"role": "user", "content": "My name is Asha and please email me."}]}, config=asha)Two customers, one manager
from langchain.chat_models import init_chat_model
from langgraph.store.memory import InMemoryStore
from langmem import create_memory_store_manager
model = init_chat_model("groq:openai/gpt-oss-120b", temperature=0)
store = InMemoryStore(index={"dims": 3072, "embed": "google_genai:gemini-embedding-2"})
manager = create_memory_store_manager(
model,
namespace=("memories", "{user_id}"),
instructions="Extract what helps support this customer. Record everything in a single Memory call.",
store=store,
)
asha = {"configurable": {"user_id": "asha"}}
ravi = {"configurable": {"user_id": "ravi"}}
manager.invoke({"messages": [{"role": "user", "content": "My name is Asha and please email me."}]}, config=asha)
manager.invoke({"messages": [{"role": "user", "content": "Text me instead, my inbox is full."}]}, config=asha)
manager.invoke({"messages": [{"role": "user", "content": "I'm Ravi. Please call me."}]}, config=ravi)
for user in ["asha", "ravi"]:
for item in store.search(("memories", user)):
print(user, "|", item.value["content"]["content"])Output
asha | Customer name: Asha. Preferred contact method: text. Request: send text communication. ravi | Customer name: Ravi. Preference: be addressed as "Ravi".
What the store holds
- Asha has one memory, with text as her contact. The second call searched her namespace, found the email memory, and patched it; the email preference is gone and nothing was duplicated.
- Ravi's memory has his name but not his request. He asked to be called; the model recorded instead that he wants to be addressed as "Ravi", which he never said. The store manager saves what the model writes, including its misses.
- The namespaces kept them apart. Asha's calls never saw Ravi's memory, and searching one customer's namespace returns only theirs.
What a store manager does on each call
- Searches the namespace for memories related to the conversation, up to
query_limitof them (an argument of the manager, 5 in version 0.0.30). - Calls the memory manager with those as existing memories.
- Puts new and updated memories in the store, and deletes removed ones when
enable_deletes=True.
Memory manager vs store manager
| create_memory_manager | create_memory_store_manager | |
|---|---|---|
| Needs a store | No | Yes |
| Existing memories | You pass them | It searches for them |
| Saving the result | Your code | It writes to the store |
| Per-user data | Your code keeps it apart | The namespace template |
When to use a store manager
- After each chat, to update what the assistant knows about that customer.
- In the background, run by Background memory.
- With a profile schema and
enable_inserts=False, to keep one profile per user in the store.
Watch out. The
user_id in the config decides whose memories are read and written. Take it from your login system, never from the message text; a wrong id shows one customer's memories to another.Related
- Previous: Semantic search
- Next: Memory tools
- Reference: How to configure dynamic namespaces
Try it yourself
- Call the manager without
configand read the error. - Use the namespace
("shop", "{user_id}", "memories")and printstore.list_namespaces(). - Pass
schemas=[Profile]andenable_inserts=Falsefrom Profiles and send two updates.
Little by little, you're building something great.