*[Watch on YouTube](https://www.youtube.com/watch?v=HqGIYRXo6WE&list=PLDzwjhH-4yhU&index=9)*

About this lesson

The videos in this course are a snapshot in time. Strands is under active development, so the code featured on this page reflects the most up-to-date patterns, but the concepts covered in the video still apply. When in doubt, trust the code.

*Code for this lesson: [`samples/09-persistent-memory`](https://github.com/aws-samples/sample-building-with-strands-course/tree/main/samples/09-persistent-memory)*

## Persisting Conversation History

Session managers persist conversation history and agent state across runs. Without them, everything resets when the process stops. They’re implemented as hook providers, so persistence is just another harness behavior layered in through hooks.

## Snapshot Session Manager (Recommended)

The recommended approach for new single-agent sessions. It saves the entire agent state as one atomic blob instead of individual message records, and supports immutable checkpoints for restoring to any prior point.

```python
from strands import Agent
from strands.session import SnapshotSessionManager
from strands.storage import LocalFileStorage

session_manager = SnapshotSessionManager(
    session_id="customer-session-001",
    storage=LocalFileStorage("./sessions"),
)

agent = Agent(
    tools=[lookup_customer, get_order_history, process_refund],
    system_prompt=SYSTEM_PROMPT,
    context_manager="auto",
    session_manager=session_manager,
)
```

Persistence happens automatically: agent state is saved after each invocation by default. Use `save_latest_on="message"` to save after every message instead.

For production, swap `LocalFileStorage` for `S3Storage`:

```python
from strands.storage import S3Storage

session_manager = SnapshotSessionManager(
    session_id="customer-session-001",
    storage=S3Storage(bucket="my-agent-sessions", prefix="production/"),
)
```

📂 [snapshot\_session\_manager.py](https://github.com/aws-samples/sample-building-with-strands-course/tree/main/samples/09-persistent-memory/snapshot_session_manager.py)

## File Session Manager (Record-Based)

The record-based approach persists each message individually. It’s still supported for existing sessions and required for Graph/Swarm multi-agent persistence.

```python
from strands import Agent
from strands.session.file_session_manager import FileSessionManager

session_manager = FileSessionManager(
    session_id="customer-session-001",
    storage_dir="./sessions",
)

agent = Agent(
    tools=[lookup_customer, get_order_history, process_refund],
    system_prompt=SYSTEM_PROMPT,
    context_manager="auto",
    session_manager=session_manager,
)
```

📂 [file\_session\_manager.py](https://github.com/aws-samples/sample-building-with-strands-course/tree/main/samples/09-persistent-memory/file_session_manager.py)

## S3 Session Manager (Record-Based)

Same record-based approach, backed by S3 instead of local disk:

```python
from strands.session.s3_session_manager import S3SessionManager

session_manager = S3SessionManager(
    session_id="customer-session-001",
    bucket="my-agent-sessions",
    prefix="customer-service/",
    region_name="us-east-1",
)

agent = Agent(..., session_manager=session_manager)
```

📂 [s3\_session\_manager.py](https://github.com/aws-samples/sample-building-with-strands-course/tree/main/samples/09-persistent-memory/s3_session_manager.py)

## When to Use Which

| Manager | Best For |
| --- | --- |
| `SnapshotSessionManager` | New single-agent sessions. Simpler, atomic saves, supports checkpoints. |
| `FileSessionManager` | Existing record-based sessions, Graph/Swarm multi-agent, bidirectional streaming. |
| `S3SessionManager` | Same as File but with S3 for cross-machine access. |

## Sessions, Memory, and Storage

Session managers are one of three related pieces, and it helps to keep them straight:

-   **Session manager**: persists the conversation so the agent can resume where it left off. Scoped to one session.
-   **Memory manager**: durable knowledge that carries across sessions (user preferences, facts, decisions) without replaying old conversations. Backed by one or more **memory stores**.
-   **Storage**: the byte-level backend underneath both. `LocalFileStorage`, `S3Storage`, and community backends implement the same `Storage` interface, so a session manager, a memory store, and the context manager’s stash can all share one backend.

Memory is opt-in and separate from sessions. Attach a `MemoryManager` with a store and the agent gets recall (a tool to search what it knows) and injection (relevant memories folded into the prompt automatically):

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

# Zero-setup store for prototyping; swap for a production store later
store = TestMemoryStore(name="customer-service")

agent = Agent(
    session_manager=session_manager,           # this conversation
    memory_manager=MemoryManager(stores=[store]),  # knowledge across conversations
)
```

## Production Storage: DynamoDB

Because sessions, memory, and offloaded context all sit on the `Storage` interface, one production backend can serve all of them. [Strands DynamoDB Storage](https://github.com/aws/strands-dynamodb-storage) is an AWS-maintained backend that fits agent workloads well: serverless, single-digit-millisecond reads, native TTL so stale sessions expire themselves, and vector search on the same table for semantic memory.

Set it once at the agent level and every subsystem that persists bytes inherits it under its own namespace:

```python
from strands import Agent
from strands.session import SnapshotSessionManager
from strands_dynamodb_storage import DynamoDBStorage

storage = DynamoDBStorage("agent-storage", region_name="us-east-1")

agent = Agent(
    tools=[lookup_customer, get_order_history, process_refund],
    system_prompt=SYSTEM_PROMPT,
    context_manager="auto",
    storage=storage,                                  # shared backend
    session_manager=SnapshotSessionManager("customer-session-001"),  # inherits storage
)
```

You own the table (a string `pk` partition key and string `sk` sort key is all it needs), and the package only ever issues `PutItem`, `GetItem`, `DeleteItem`, and `Query`.

## More Backends

The integrations catalog lists additional session managers, memory stores, and storage backends. They implement the same interfaces, so you can swap them in without changing agent code.

| Integration | What It Is |
| --- | --- |
| [Strands DynamoDB Storage](https://github.com/aws/strands-dynamodb-storage) | `Storage` backend on Amazon DynamoDB, with TTL, S3 offload, and vector search |
| [AgentCore Memory](/pr-cms-4519/docs/integrations/session-managers/agentcore-memory/index.md) | Session manager backed by Amazon Bedrock AgentCore Memory, with long-term recall |
| [Valkey Session Manager](/pr-cms-4519/docs/integrations/session-managers/strands-valkey-session-manager/index.md) | Session manager on Valkey (Redis-compatible) for fast distributed storage |
| [Memory stores](/pr-cms-4519/docs/integrations/memory-stores/overview/index.md) | Community-built `MemoryStore` backends for the `MemoryManager` |
| [Storage backends](/pr-cms-4519/docs/integrations/storage/overview/index.md) | Community-built `Storage` implementations |

## Resources

-   📖 [Session Management](/pr-cms-4519/docs/user-guide/sdk/agents/session-management/index.md)
-   📖 [Memory](/pr-cms-4519/docs/user-guide/sdk/memory/overview/index.md)
-   📖 [Storage](/pr-cms-4519/docs/user-guide/sdk/storage/index.md)
-   📖 [Control what your agent remembers](/pr-cms-4519/docs/user-guide/sdk/memory/managing-memory/index.md)