The first time I deployed an agent to production, I watched it handle 200 conversations perfectly. Then I restarted the service for a deployment at 2 AM. The next morning the agent greeted the same users as if it had never seen them before. No memory of preferences they had confirmed. No record of issues already resolved. Back to zero.

That experience taught me the fundamental rule of agent memory: a session that cannot be serialized is a session that does not survive a restart. The entire conversation you just had, the facts you established, the reasoning you built across dozens of turns, lives only in the context window of a running process. Kill that process and you have nothing.

This is the serialization problem. And it is harder than it looks.

The Three Approaches Engineers Actually Use

I have seen three real patterns in production systems. Each one solves the problem but creates a different tradeoff.

Full state serialization means dumping the entire conversation history plus the system prompt into a structured format on disk. JSON works. So does msgpack if you want speed. The agent restarts, reads the file, and gets its full context back.

The advantage is completeness. Nothing gets lost. The disadvantage is cost and latency. A 6-month conversation history is enormous. You cannot fit that into a context window, or if you can, you are paying to re-process it on every restart. I measured re-processing a 500-message history at roughly 3 seconds of added latency on a Claude Sonnet call with a 200k context window.

Conversation log storage is the cheaper version. You write every message to a database as it happens. On restart, you retrieve the recent messages and give the agent the raw log. This is what I see most teams do initially.

The agent reconstructs context from the log. The problem is that reconstruction is imprecise. The agent still has to identify what matters, what to act on first, what to ignore. For a short conversation this works fine. For a months-long relationship with a user, the agent spends significant tokens figuring out where things stand before it can actually help.

Selective serialization is the pattern I recommend once you understand your agent well enough. You define a state schema that captures what actually matters. User preferences, confirmed facts, current task status, unresolved issues. The agent updates this schema as it goes.

# A minimal serialization schema for a research agent
{
    "user_preferences": {
        "communication_style": "concise",
        "timezone": "America/New_York"
    },
    "confirmed_facts": [
        {"fact": "user is working on a RAG pipeline",
         "confirmed_at": "2026-04-28T14:22:00Z"},
        {"fact": "user prefers pgvector over Pinecone",
         "confirmed_at": "2026-04-29T09:15:00Z"}
    ],
    "active_task": {
        "description": "benchmark hybrid search accuracy",
        "status": "in_progress",
        "last_action": "ran evaluation script, results pending"
    }
}

The tradeoff is upfront design work. You need to understand what your agent needs to remember before you can define the schema. But the resulting state is small, fast to load, and semantically meaningful.

When Serialization Fails in Practice

Schema mismatch is the failure mode I see most often in production. You designed your serialization schema six months ago. Your agent has evolved. You added new capabilities. The new code writes state using keys that did not exist in the original schema. Old sessions deserialize with those keys missing. The agent does not crash, it just quietly behaves as if certain facts were never established.

I handle this by versioning the schema explicitly. The serialized state includes a schema version field. On deserialization, I run a migration function that maps old versions to the current schema before the agent processes anything.

Stale state is a different problem. A customer support agent serialized three days ago has state that may no longer reflect reality. The customer may have resolved their issue through another channel. The product may have changed. The agent proceeding from stale state can be worse than an agent with no memory at all.

The fix is to validate and refresh on deserialization. Check timestamps. Confirm critical facts before acting on them. Give the agent a way to say I need to re-verify this rather than assuming.

The Schema Design Decisions That Matter

Context window size drives a lot of the serialization strategy. A 1M token context window from Gemini 2.5 Pro changes what you can serialize compared to a 200k window from Claude 3.5 Sonnet. With a large context window, you can afford to serialize full recent history and let the agent sort through it on load. With a smaller window, you need to be surgical about what goes into serialized state.

I serialize the conversation log separately from structured state. The log is append-only and grows unbounded. The structured state is what the agent actively uses to make decisions. I keep a sliding window of recent log entries for reconstruction and serialize the structured state independently.

Cloud-native serialization matters if you run multiple agent instances. SQLite works on a single instance. If you are running across containers or regions, the serialized state needs to go somewhere shared. I use S3 with JSON for most projects. The added latency for a GET on startup is typically under 50ms for a well-designed schema under 100KB.

What Serialization Cannot Solve

Serialization handles session continuity. It does not solve the retrieval problem. If you serialize a conversation but have no way to find the relevant parts quickly on retrieval, you end up with context that is technically there but practically unusable.

The memory hierarchy matters here. Serialized state is one layer. How you index and retrieve from that state is another. My post on the memory hierarchy goes into this in detail, but the short version is that serialization and retrieval are separate problems that need to be designed together.

Agent memory retrieval is also asymmetric. What you serialize is not always what you retrieve. I wrote about this in my post on asymmetric retrieval in agent memory. The schema you design for serialization shapes what retrieval looks like, and if you get the schema wrong, the retrieval will be wrong in predictable ways.

The serialization format itself matters less than the discipline of using it consistently. JSON is fine for most cases. If you are writing to disk on every action for an agent handling 10,000 requests per minute, you need something faster. msgpack or Protocol Buffers cut serialization overhead by 5x in my benchmarks. But for the vast majority of agents, JSON with a clear schema is readable, debuggable, and sufficient.

The Bottom Line

If you are building an agent that users interact with over days or weeks, serialization is not optional. It is the mechanism that makes long-term relationships possible. The pattern you choose shapes everything downstream: retrieval quality, context window utilization, latency on restart, and the agent's ability to actually use what it learned.

Start with a clear state schema. Serialize what matters. Validate on deserialization. And test your restart path explicitly. An agent that works perfectly in a long-running session but loses everything on restart is an agent your users will not trust.