---
title: Snapshots
description: "Capture and restore agent state at any point in time. Use snapshots for checkpointing, undo/redo, branching conversations, and custom persistence."
---

Snapshots capture agent state at a point in time so you can save and restore it later. You choose which fields to include — either by picking a preset (a preconfigured set of fields) or by specifying fields directly — and you can further refine with includes and excludes. Snapshots are plain JSON-serializable objects — persistence is up to you.

## Basic Usage

### Taking a Snapshot

Use the `"session"` preset to capture the most common fields:

<Tabs>
<Tab label="Python">

```python
from strands import Agent

agent = Agent(system_prompt="You are a helpful assistant")
agent("Hello!")
agent.state.set("user_id", "user-123")

# Capture a snapshot with the session preset
snapshot = agent.take_snapshot(preset="session")

print(snapshot.schema_version)  # "1.0"
print(snapshot.created_at)      # ISO 8601 timestamp
print(snapshot.data.keys())     # messages, state, conversation_manager_state, interrupt_state
```

The `"session"` preset captures `messages`, `state`, `conversation_manager_state`, and `interrupt_state`. The `system_prompt` field is not included by default — see [Field Selection](#field-selection) to customize which fields are captured.
</Tab>
<Tab label="TypeScript">

```typescript
--8<-- "user-guide/concepts/agents/snapshots_imports.ts:imports"

--8<-- "user-guide/concepts/agents/snapshots.ts:take_snapshot"
```

The `"session"` preset captures `messages`, `state`, `systemPrompt`, `modelState`, and `interrupts`.
</Tab>
</Tabs>

### Restoring a Snapshot

Load a snapshot to restore the agent to a previous state:

<Tabs>
<Tab label="Python">

```python
from strands import Agent

agent = Agent(system_prompt="You are a helpful assistant")
agent("Hello!")

# Take a snapshot
snapshot = agent.take_snapshot(preset="session")

# Continue the conversation
agent("Tell me a joke")
agent("Tell me another one")

# Restore to the earlier state
agent.load_snapshot(snapshot)

# The agent is back to the state after "Hello!"
print(len(agent.messages))  # Only the messages from before the jokes
```
</Tab>
<Tab label="TypeScript">

```typescript
--8<-- "user-guide/concepts/agents/snapshots_imports.ts:imports"

--8<-- "user-guide/concepts/agents/snapshots.ts:load_snapshot"
```
</Tab>
</Tabs>

Only fields present in the snapshot are restored. If a field was not included when the snapshot was taken, the agent's current value for that field is left unchanged.

## Field Selection

Snapshots support flexible field selection through presets, includes, and excludes. The resolution order is: **preset → include → exclude** — start with the fields defined by the preset, add any fields listed in `include`, then remove any fields listed in `exclude`.

<Tabs>
<Tab label="Python">

| Field | Description |
|-------|-------------|
| `messages` | Conversation history |
| `state` | Agent key-value state |
| `conversation_manager_state` | Conversation manager internal state |
| `interrupt_state` | Human-in-the-loop interrupt state |
| `system_prompt` | System prompt content |

</Tab>
<Tab label="TypeScript">

| Field | Description |
|-------|-------------|
| `messages` | Conversation history |
| `state` | Agent key-value state (appState) |
| `systemPrompt` | System prompt content |
| `modelState` | Model provider state (e.g. response IDs for stateful models) |
| `interrupts` | Human-in-the-loop interrupt state |

</Tab>
</Tabs>

:::note
The `"session"` preset is currently the only available preset. It includes the same fields that the [Session Manager](./session-management.mdx) persists by default.
:::

Use `include` to select specific fields without a preset, or to add fields on top of a preset. Use `exclude` to remove fields from a preset:

<Tabs>
<Tab label="Python">

```python
# Capture only messages and state (no preset)
snapshot = agent.take_snapshot(include=["messages", "state"])

# Session preset plus system_prompt
snapshot = agent.take_snapshot(preset="session", include=["system_prompt"])

# Session preset minus interrupt_state
snapshot = agent.take_snapshot(preset="session", exclude=["interrupt_state"])
```
</Tab>
<Tab label="TypeScript">

```typescript
--8<-- "user-guide/concepts/agents/snapshots_imports.ts:imports"

--8<-- "user-guide/concepts/agents/snapshots.ts:field_selection"
```
</Tab>
</Tabs>

## Application Data

Snapshots support an `app_data` (Python) / `appData` (TypeScript) field for storing application-owned data alongside the agent state. Strands does not read or modify this data — it's passed through verbatim.

This is useful for attaching metadata like a display name for the snapshot, the current step in a workflow, user preferences, or any other context your application needs to associate with a particular point in time.

<Tabs>
<Tab label="Python">

```python
snapshot = agent.take_snapshot(
    preset="session",
    app_data={
        "snapshot_label": "After onboarding",
        "workflow_step": 3,
        "user_display_name": "Alice",
    },
)

# Access app data later
print(snapshot.app_data["snapshot_label"])     # "After onboarding"
print(snapshot.app_data["user_display_name"])  # "Alice"
```
</Tab>
<Tab label="TypeScript">

```typescript
--8<-- "user-guide/concepts/agents/snapshots_imports.ts:imports"

--8<-- "user-guide/concepts/agents/snapshots.ts:app_data"
```
</Tab>
</Tabs>

## Serialization

Snapshots are JSON-serializable, making them easy to persist to any storage backend.

<Tabs>
<Tab label="Python">

```python
import json
from strands import Agent, Snapshot

agent = Agent()
agent("Hello!")

# Take a snapshot
snapshot = agent.take_snapshot(preset="session")

# Serialize to JSON
json_str = json.dumps(snapshot.to_dict())

# Store to file, database, S3, etc.
with open("snapshot.json", "w") as f:
    f.write(json_str)

# Later, restore from JSON
with open("snapshot.json", "r") as f:
    data = json.loads(f.read())

restored_snapshot = Snapshot.from_dict(data)

# Load into a new agent
new_agent = Agent()
new_agent.load_snapshot(restored_snapshot)
```
</Tab>
<Tab label="TypeScript">

```typescript
--8<-- "user-guide/concepts/agents/snapshots_imports.ts:imports_snapshot"

--8<-- "user-guide/concepts/agents/snapshots.ts:serialization"
```
</Tab>
</Tabs>

## Use Cases

### Checkpointing

Save agent state at key points in a workflow so you can resume from the last checkpoint if something goes wrong:

<Tabs>
<Tab label="Python">

```python
from strands import Agent

agent = Agent(system_prompt="You are a research assistant")

# Step 1: Gather information
agent("Research the latest trends in AI agents")
checkpoint_1 = agent.take_snapshot(preset="session")

# Step 2: Analyze (might fail or produce poor results)
agent("Analyze the key themes and summarize")
checkpoint_2 = agent.take_snapshot(preset="session")

# If step 2 didn't go well, roll back to checkpoint 1
agent.load_snapshot(checkpoint_1)
agent("Focus specifically on multi-agent systems and summarize")
```
</Tab>
<Tab label="TypeScript">

```typescript
--8<-- "user-guide/concepts/agents/snapshots_imports.ts:imports"

--8<-- "user-guide/concepts/agents/snapshots.ts:checkpointing"
```
</Tab>
</Tabs>

### Branching Conversations

Create multiple conversation branches from the same starting point:

<Tabs>
<Tab label="Python">

```python
from strands import Agent

agent = Agent(system_prompt="You are a creative writer")
agent("Write the opening paragraph of a mystery novel")

# Save the branch point
branch_point = agent.take_snapshot(preset="session")

# Branch A: formal tone
agent("Continue in a formal, academic tone")
formal_snapshot = agent.take_snapshot(preset="session")

# Branch B: go back and try casual tone
agent.load_snapshot(branch_point)
agent("Continue in a casual, conversational tone")
casual_snapshot = agent.take_snapshot(preset="session")
```
</Tab>
<Tab label="TypeScript">

```typescript
--8<-- "user-guide/concepts/agents/snapshots_imports.ts:imports"

--8<-- "user-guide/concepts/agents/snapshots.ts:branching"
```
</Tab>
</Tabs>

## Relationship to Session Management

[Session management](./session-management.mdx) handles persistence automatically — state is saved and restored at the right lifecycle points without you writing any persistence code. Snapshots give you manual control: you decide when to capture state, what to include, and where to store it. Use session management when you want hands-off persistence, and snapshots when you need precise control over save points.

## See Also

- [State Management](./state.mdx) — Conversation history, agent state, and request state
- [Session Management](./session-management.mdx) — Automatic persistence with file or S3 storage
- [Conversation Management](./conversation-management.mdx) — Managing conversation history and context window
