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

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. This protocol enforces three core operations:

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.

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 (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.

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 (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.

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, 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:

Swapping Implementations

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

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) 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. 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →