Choose persistence based on what you need to recover: a conversation, or unfinished execution.

Three kinds of state

State Storage Recovery
Ordinary Agent Process memory Lives as long as the instance
Agent snapshot Explicit files in a session directory Restore configuration, messages, usage, and supported extension state
AgentRuntime SQLite, PostgreSQL, or Temporal Resume persisted execution under replay and approval policies

Repeated calls to the same Agent keep its conversation. That alone does not make a session durable.

Save a conversation snapshot

from harnessx import Agent

async def save_and_continue():
    async with Agent() as agent:
        await agent.run("Remember that this project analyzes invoices.")
        session_id = await agent.save_session(storage_dir=".agent_sessions")

    async with await Agent.load_session(
        session_id, storage_dir=".agent_sessions"
    ) as restored:
        result = await restored.run("What does this project analyze?")
        return result

Snapshots contain serializable state, not executable Python handlers or live MCP connections. Rebind custom tools and provide compatible extensions when loading them. Supply the same extension names; explicitly supplied configuration must match the snapshot. Snapshots written by harnessx 0.3 load in 0.4 (AgentConfig.from_dict() reads both configuration shapes); state written by 0.4 does not load in 0.3.

When you need crash recovery

Use AgentRuntime when you need to recover an unfinished run or preserve an approval wait across process restarts. This is covered under Advanced topics → Durable agent runs.

That guide explains AgentRuntime(agent, backend=backend), session IDs and run IDs, explicit resume, RunHandle, RunResult, event cursors, approvals, and resource ownership. The PostgreSQL walkthrough provides a runnable crash/restart demonstration.

Saving a conversation snapshot and persisting execution are separate operations. Loading a snapshot does not resume an in-flight tool call.

Browser chat state is separate

The current harness-web demo keeps chat IDs, run IDs, messages, and live MCP connections in server memory. Skills and generated files live on disk. Browser refresh preserves a live server's conversations; server restart does not restore them. The demo has not yet adopted durable web session storage.

Ownership

A runtime closes the agent it executes. It closes a backend only if it created that backend. Explicitly close injected backends, providers, and other caller-owned resources. Agent instances support one active run at a time.