# StateBackend vs FilesystemBackend in DeepAgents: Storage Architecture Compared

> Compare StateBackend vs FilesystemBackend in DeepAgents. Understand how StateBackend offers isolated agent state while FilesystemBackend ensures persistent storage.

- Repository: [LangChain/deepagents](https://github.com/langchain-ai/deepagents)
- Tags: architecture
- Published: 2026-03-17

---

**StateBackend stores files in ephemeral LangGraph agent state while FilesystemBackend writes to the host machine's persistent filesystem, with the former offering isolation and the latter offering durability across sessions.**

The `langchain-ai/deepagents` repository provides two distinct storage implementations for agent file operations. Understanding the difference between **StateBackend and FilesystemBackend in deepagents** is crucial for building secure, persistent AI applications that match your deployment environment's requirements.

## Core Architectural Differences

Both backends implement the same `BackendProtocol` interface, but they diverge significantly in where and how they store data.

### StateBackend Implementation

In [`deepagents/backends/state.py`](https://github.com/langchain-ai/deepagents/blob/main/deepagents/backends/state.py), the **StateBackend** maintains files inside the LangGraph agent state as a Python dictionary. The backend stores data in `runtime.state["files"]`, making it accessible only within the current conversation thread. Binary data is encoded as base-64 strings (or plain text for V2 format), and metadata is manually tracked within the state dict.

### FilesystemBackend Implementation

The **FilesystemBackend** in [`deepagents/backends/filesystem.py`](https://github.com/langchain-ai/deepagents/blob/main/deepagents/backends/filesystem.py) interacts directly with the host operating system's filesystem using `pathlib.Path` and `os.open`. This backend supports real path resolution through the `_resolve_path()` method and provides accurate file metadata via OS `stat` calls.

## Persistence and Security Models

The choice between these backends fundamentally affects how long files survive and who can access them.

### Ephemeral vs Persistent Storage

**StateBackend** offers ephemeral storage that disappears when the thread ends or state is cleared. Each conversation thread receives an isolated set of files, making it ideal for temporary coding assistants or CI/CD steps where output is captured in LangGraph checkpoints.

**FilesystemBackend** provides persistent storage across invocations. Agents can read and write the same files over many sessions, with changes surviving application restarts. This suits local development tools that must edit actual source files or interact with existing project structures.

### Security Considerations

**StateBackend** is safe by default. Agents can only access the in-memory state they own, preventing accidental reads of host secrets or system files.

**FilesystemBackend** grants unrestricted read/write access to the host filesystem by default. When `virtual_mode=True` and `root_dir` are configured, the backend treats paths as virtual under a specified root directory and blocks traversal attempts (`..`, `~`). According to the source code, this backend should only be used in trusted environments or behind Human-in-the-Loop middleware.

## Practical Usage Examples

### Initializing Each Backend

```python
from deepagents.backends.state import StateBackend
from deepagents.backends.filesystem import FilesystemBackend

# Ephemeral state-based storage

state_backend = StateBackend(runtime=my_tool_runtime, file_format="v2")

# Persistent filesystem with virtual sandbox

fs_backend = FilesystemBackend(root_dir="my_project", virtual_mode=True)

```

### Writing Files

With **StateBackend**, writes return a `files_update` dictionary that LangGraph merges into the checkpoint:

```python
result = state_backend.write("/notes/todo.txt", "Buy milk\n")
print(result.files_update)  # Dict merged into runtime.state["files"]

```

With **FilesystemBackend**, writes go directly to disk:

```python
result = fs_backend.write("notes/todo.txt", "Buy milk\n")

# files_update is None; the OS filesystem is the source of truth

```

### Listing Directory Contents

**StateBackend** lists keys from the state dictionary:

```python
ls = state_backend.ls_info("/")
for entry in ls.entries:
    print(entry["path"], entry["is_dir"])

```

**FilesystemBackend** provides rich OS metadata:

```python
ls = fs_backend.ls_info("/")
for entry in ls.entries:
    print(entry["path"], entry["size"], entry["modified_at"])

```

### Security Configuration

To prevent directory traversal attacks with **FilesystemBackend**:

```python
backend = FilesystemBackend(root_dir="/tmp/agent_workspace", virtual_mode=True)

try:
    backend.write("../secret.txt", "data")
except ValueError as e:
    print("Blocked:", e)  # Escaping root_dir raises ValueError

```

## Choosing the Right Backend for Your Use Case

Select **StateBackend** when:

- Building short-lived coding assistants that need temporary files
- Running CI/CD steps where agent output is captured in LangGraph checkpoints
- Operating in environments where exposing the host filesystem is unsafe

Select **FilesystemBackend** when:

- Developing local tools that must edit actual source files
- Agents need to interact with existing project files across multiple sessions
- Persistent file storage is required between agent invocations

## Summary

- **StateBackend** stores files in `runtime.state["files"]` as ephemeral, base-64 encoded data that disappears when the conversation thread ends
- **FilesystemBackend** writes to the host OS filesystem using `pathlib.Path` and persists across application restarts
- **StateBackend** provides isolation by default, while **FilesystemBackend** requires `virtual_mode=True` and `root_dir` to sandbox agents
- Both implement `BackendProtocol` and support `write()`, `ls_info()`, and path resolution, but differ in metadata accuracy and binary handling
- Choose **StateBackend** for security-sensitive, temporary operations and **FilesystemBackend** for persistent, development-focused workflows

## Frequently Asked Questions

### When should I use StateBackend over FilesystemBackend?

Use **StateBackend** when you need ephemeral storage that isolates each conversation thread from the host system. It is ideal for production environments where agents should not access sensitive host files, or for temporary coding tasks where file persistence beyond the current session is unnecessary.

### Can FilesystemBackend prevent agents from accessing sensitive files?

Yes, but only when configured with `virtual_mode=True` and a restricted `root_dir`. By default, **FilesystemBackend** allows access to any absolute path on the host system. When virtual mode is enabled, the `_resolve_path()` method blocks traversal attempts outside the specified root directory, though the documentation recommends using this backend only in trusted environments.

### How does StateBackend handle binary files?

**StateBackend** encodes binary data as base-64 strings stored within the state dictionary (or as plain text in V2 format). This approach ensures binary content remains serializable for LangGraph checkpoints, though it requires manual metadata tracking since the files do not exist on the actual filesystem.

### Are both backends compatible with all DeepAgents tools?

Yes, both **StateBackend** and **FilesystemBackend** implement the same `BackendProtocol` interface defined in the deepagents architecture. Tools using `write()`, `read()`, `ls_info()`, or `grep()` operations work identically with either backend, though **FilesystemBackend** offers additional capabilities like `ripgrep` integration and accurate file timestamps that **StateBackend** cannot provide.