# AISuite State Persistence Options: In‑Memory, File‑Based, and PostgreSQL Storage Guide

> Explore AISuite state persistence options: In-Memory, File-Based, and PostgreSQL storage. Learn how to save, load, and delete agent run state efficiently with this guide.

- Repository: [Andrew Ng/aisuite](https://github.com/andrewyng/aisuite)
- Tags: how-to-guide
- Published: 2026-08-03

---

**AISuite provides three interchangeable state stores—`InMemoryStateStore`, `FileStateStore`, and `PostgresStateStore`—that all implement the same `StateStore` protocol for saving, loading, and deleting agent run state.**

Choosing the right AISuite state persistence option depends on your deployment needs: ephemeral testing, local file durability, or production-grade database reliability. Each implementation in the `andrewyng/aisuite` repository shares an identical API, letting you swap backends without changing agent code.

## The StateStore Protocol

All persistence implementations conform to the `StateStore` protocol defined in [`aisuite/agents/state_store.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/agents/state_store.py). This protocol enforces three core operations:

```python
class StateStore(Protocol):
    def save_state(self, thread_id: str, state: RunState, *, revision: int | None = None,
                   metadata: Optional[dict[str, Any]] = None) -> StoredRunState: ...
    def load_state(self, thread_id: str) -> Optional[StoredRunState]: ...
    def delete_state(self, thread_id: str) -> None: ...

```

The **revision** parameter enables **optimistic concurrency control**. When provided, the internal `_assert_revision` helper raises `StateConflictError` if the stored revision has changed—protecting against race conditions in concurrent environments.

## In‑Memory State Storage

**`InMemoryStateStore`** is the fastest AISuite state persistence option, ideal for unit tests and short-lived scripts.

```python
from aisuite.agents.state_store import InMemoryStateStore

# Create store—no external dependencies required

mem_store = InMemoryStateStore()

# Save and immediately retrieve state

mem_store.save_state(thread_id="demo", state=RunState(...))
loaded = mem_store.load_state("demo")

```

Implementation details from [`aisuite/agents/state_store.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/agents/state_store.py) (lines 68–99):

- Stores `StoredRunState` objects in a plain Python dictionary keyed by `thread_id`
- Zero serialization overhead—direct object references
- **State vanishes when the Python process exits**

Use this when you need speed and don't require durability across restarts.

## File‑Based State Storage

**`FileStateStore`** persists agent state to JSON files on disk, providing durability without database infrastructure.

```python
from aisuite.agents.state_store import FileStateStore

# Configure with custom root directory (default: .aisuite/state)

file_store = FileStateStore(root="./my_agent_state")

# State persists across process restarts

file_store.save_state(thread_id="demo", state=RunState(...))
loaded = file_store.load_state("demo")  # Available after restart

```

Found in [`aisuite/agents/state_store.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/agents/state_store.py) (lines 101–149), this implementation:

- Serializes each `StoredRunState` to individual JSON files
- Uses **atomic write operations** to prevent corruption during crashes
- Creates directory structure automatically under the configured root

This middle-ground option suits single-node deployments and development workflows where PostgreSQL would be overkill.

## PostgreSQL State Storage

**`PostgresStateStore`** delivers production-grade durability with relational integrity and advanced features exclusive to this backend.

```python
from aisuite.agents.postgres_state_store import PostgresStateStore

# Initialize with automatic schema creation

pg_store = PostgresStateStore.from_dsn(
    "postgresql://user:password@localhost/aisuite",
    create_schema=True
)

pg_store.save_state(thread_id="demo", state=RunState(...), revision=1)

# Exclusive: compact long-running conversations

pg_store.compact_state(
    thread_id="demo",
    source_message_ids=["msg1", "msg2", "msg3"],
    summary_message={"role": "assistant", "content": "Summary of analysis..."}
)

```

As implemented in [`aisuite/agents/postgres_state_store.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/agents/postgres_state_store.py), this store:

- Maps state to three relational tables: `agent_thread_heads`, `agent_messages`, `agent_compactions`
- Enforces optimistic concurrency via revision checks at the database level
- Supports **compaction**: replace message chains with summaries while preserving provenance—critical for managing long-running agent conversations

## Comparison of AISuite State Persistence Options

| Feature | `InMemoryStateStore` | `FileStateStore` | `PostgresStateStore` |
|--------|----------------------|------------------|------------------------|
| Persistence | Process lifetime only | Filesystem durability | Database durability |
| Setup complexity | None | Directory permissions | PostgreSQL server + schema |
| Concurrency safety | None (single process) | Atomic writes per file | Full optimistic locking |
| Compaction support | No | No | **Yes** |
| Metadata storage | Yes | Yes | Yes |
| Best for | Tests, demos | Local development, simple deployments | Production, distributed systems |

## Key Implementation Files

Understanding the source structure helps when extending or debugging AISuite state persistence:

- **[`aisuite/agents/state_store.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/agents/state_store.py)** — `StoredRunState` dataclass, `StateStore` protocol, and in-memory/file implementations
- **[`aisuite/agents/postgres_state_store.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/agents/postgres_state_store.py)** — PostgreSQL backend with schema management and compaction logic
- **[`aisuite/agents/types.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/agents/types.py)** — `RunState` model that all stores serialize and deserialize
- **[`aisuite/agents/utils.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/agents/utils.py)** — Shared utilities (`now`, `new_id`) for timestamps and identifiers

## Swapping Implementations

The protocol-based design makes backend substitution trivial. Configuration might look like:

```python
def create_store(config: dict):
    match config["type"]:
        case "memory":
            return InMemoryStateStore()
        case "file":
            return FileStateStore(root=config["path"])
        case "postgres":
            return PostgresStateStore.from_dsn(config["dsn"], create_schema=True)
        case _:
            raise ValueError(f"Unknown store type: {config['type']}")

```

Your agent runner receives the store instance and remains implementation-agnostic.

## Summary

- **AISuite state persistence** requires no code changes when switching between the three built-in stores
- **InMemoryStateStore** (`aisuite/agents/state_store.py:68-99`) offers maximum speed with zero durability
- **FileStateStore** (`aisuite/agents/state_store.py:101-149`) provides simple, atomic file-based persistence
- **PostgresStateStore** ([`aisuite/agents/postgres_state_store.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/agents/postgres_state_store.py)) delivers enterprise features including compaction and optimistic concurrency
- All stores accept optional **metadata** and support **revision-based conflict detection**

## Frequently Asked Questions

### How do I migrate from file-based to PostgreSQL storage in AISuite?

Export your `StoredRunState` objects using `FileStateStore.load_state()`, then persist them with `PostgresStateStore.save_state()`. The identical protocol means no agent code changes—only the store instantiation differs.

### What happens if two processes call `save_state` on the same thread simultaneously?

With `InMemoryStateStore`, last-write-wins applies and data may be lost. `FileStateStore` uses atomic writes that prevent corruption but don't merge changes. `PostgresStateStore` raises `StateConflictError` when revisions mismatch, forcing explicit conflict resolution.

### Does PostgreSQL compaction delete original messages permanently?

No—`PostgresStateStore.compact_state()` preserves provenance by storing the summary in `agent_compactions` while marking source messages. The original message IDs remain in `agent_messages` with references intact, enabling audit trails and potential reconstruction.

### Can I implement a custom state store for Redis or DynamoDB?

Yes. Subclass any store or implement the `StateStore` protocol directly in [`aisuite/agents/state_store.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/agents/state_store.py). Your class must provide `save_state`, `load_state`, and `delete_state` methods with matching signatures. The protocol design was intentionally minimal to simplify custom backends.