# Strands Agents memory: how to add long-term memory to a Strands agent (MemoryManager, stores and per-user recall)

*Disclosure: I'm Mohammed, founder of MemorySync. I drafted this with AI assistance and checked it against the Strands Agents docs and MemorySync's Strands guide. Code status: on Oct 25, 2026 I installed strands-agents 1.62.0 and strands-memorysync 1.1.0 on Python 3.13 and ran every import and constructor below (agent, MemoryManager, TestMemoryStore, MemorySyncStore with InvocationTrigger, `get_tools()`). I also ran one `agent(...)` turn end to end with a scripted stand-in model and MemorySync's HTTP responses mocked locally, to see what the store sends and what reaches the model. No live LLM or live MemorySync API call was made.*

By default a Strands agent starts each conversation from zero. Strands Agents memory is one of three kinds of state the Strands docs separate ([memory overview](https://strandsagents.com/docs/user-guide/sdk/memory/overview/)):

- **Session management** persists the full conversation so you can resume it.
- **Conversation management** keeps a session inside the context window.
- **Memory** carries durable knowledge *across* sessions without replaying old conversations.

If your agent "forgets the user" between sessions, you need the third one.

## How Strands memory works

You attach a `MemoryManager` with one or more **stores**. Across those stores, the manager does three jobs:

1. **Recall**: the agent searches memory on demand through a tool.
2. **Injection**: relevant memories are added to the prompt automatically before the model runs.
3. **Extraction**: conversation messages are turned into memories and written to stores.

Recall and injection are on by default when you attach a store. Writing is opt-in.

## Step 1: Prototype with the local test store

```python
from strands import Agent
from strands.memory import MemoryManager
from strands.vended_memory_stores.test_memory_store import TestMemoryStore

# Persists to ~/.strands/memory/notes.json by default.
store = TestMemoryStore(name="notes")
agent = Agent(memory_manager=MemoryManager(stores=[store]))
```

This ran as written. It's fine on your laptop, but a JSON file in a home directory isn't per-user and won't follow a container redeploy. For production, Strands documents an Amazon Bedrock Knowledge Base store, a file store on any storage backend, and a custom-store interface.

## Step 2: Swap in a per-user hosted store

MemorySync ships `strands-memorysync`, a store for the same MemoryManager ([guide](https://docs.memorysync.io/guides/strands?utm_source=hashnode&utm_medium=organic_page&utm_campaign=v5_oct25&utm_content=pseo_strands-agents-long-term-memory)). It needs Python 3.10+, a Strands release with the MemoryManager (2026+), and a MemorySync API key in `MEMORYSYNC_API_KEY`.

```bash
pip install strands-agents strands-memorysync
```

```python
from strands import Agent
from strands.memory import MemoryManager, InvocationTrigger
from strands_memorysync import MemorySyncStore

store = MemorySyncStore(
    user_id="customer-42",        # required: whose memories these are
    session_id="support",         # optional: tags this conversation's facts
    extraction={"trigger": InvocationTrigger()},  # send every turn, see below
)

agent = Agent(memory_manager=MemoryManager(stores=[store]))
agent("Which seat should I book?")
```

What happens: before every model call, the manager asks the store for relevant memories and injects them. After each exchange, only the **user's** messages are sent for fact extraction. Assistant replies, tool messages and system messages are not sent. In my local run (stand-in model, mocked API), the recalled memory showed up in the model's input, and the only write was the user's message with `role: "user"`. The assistant's reply was not sent.

## Step 3: Fix the "first few turns are forgotten" surprise

Strands' default extraction trigger fires every five invocations, so a user's first exchanges aren't written yet and early recalls come back empty. That's by design. The synchronous `agent(...)` call also flushes after each call, but `invoke_async` does not. If you want memories from the first exchange, pass `InvocationTrigger()` as above. In my local run, the first turn's user message was written right after that first call. The MemorySync guide recommends this because its writes are idempotent (a retry isn't extracted twice).

## Step 4: Pick a stable `user_id`

Use your own user ID, an email or a UUID, and use the **same** value every session. A different value means an empty recall. The `user_id` is also the isolation boundary between your users. Create one store per user (or per request) rather than sharing one store across users.

## Optional: explicit memory tools

```python
tools = store.get_tools()   # -> memorysync_search, memorysync_save
```

I confirmed these two names on the box, and the defaults in the table below against the installed `MemorySyncStore` signature. There's deliberately no delete tool, so deletion stays an API or admin action, and the user identity is never a tool parameter the model can change.

## Useful knobs

| Parameter | Default | What it does |
|---|---|---|
| `top_k` | 5 | Memories considered per model call |
| `min_prompt_chars` | 8 | Skip recall for trivial prompts |
| `writable` | True | Allow extraction writes |

## Common questions

**Do I still need a session manager?** Yes, if you want to resume the exact conversation. Memory and session persistence solve different problems, and Strands documents them separately.

**Why are recalls empty right after I store something?** Extraction runs asynchronously, so give it a moment. Also check that both runs use the same `user_id`, and that you're not on the five-turn default trigger.

**`ModuleNotFoundError: strands`?** Install the framework itself: `pip install strands-agents`.

Want to watch a fact survive a page reload before you wire it in? **[Try MemorySync in the browser](https://memorysync.io/try?utm_source=hashnode&utm_medium=organic_page&utm_campaign=v5_oct25&utm_content=pseo_strands-agents-long-term-memory)**. No signup is needed.

## Sources

- Strands Agents, Memory overview: https://strandsagents.com/docs/user-guide/sdk/memory/overview/
- Strands Agents, Control what the agent remembers: https://strandsagents.com/docs/user-guide/sdk/memory/managing-memory/
- MemorySync Strands Agents guide: https://docs.memorysync.io/guides/strands
- strands-memorysync on PyPI: https://pypi.org/project/strands-memorysync/
