Agent State Schema Design for Resumable Workflows
Preserve workflow progress across LLM timeouts by storing state durably instead of in memory.

An agent is three hours into a multi-step workflow. Then that call times out. Without explicit state persistence, the entire run is gone, and the only option is to start over from step one.
That failure mode is the whole problem in miniature. LLMs are stateless by design: each call is a fresh inference with no memory of what came before unless something outside the model carries that memory forward. The work assigned to agents is long-running, multi-step, and full of dependencies between one action and the next.
Most teams' first instinct when a workflow fails is to retry from scratch. It falls apart on a workflow that runs for hours, because retrying from zero means paying for inference on steps that already succeeded, and worse, it risks re-running steps that had side effects: an email already sent, a charge already applied, both now duplicated.
The fix starts with a change in how the agent gets framed. Rather than a long-running function that either completes or dies, an agent is a resumable state machine, where getting interrupted is just another transition the system expects, not an exception that breaks it. One rule follows directly from that framing: the model itself should never hold the only copy of progress. If the only record of what happened lives inside the context window of a single inference call, that record vanishes the moment the process dies.
Session state and workflow state mark a practical boundary, not a technical nuance. Session state lives in RAM or a cache and disappears the moment a process restarts. Workflow state lives in durable storage and survives crashes, reboots, and pauses that stretch across days. Everything that follows in schema design comes down to building workflow state deliberately, instead of accidentally depending on session state and discovering the difference during an outage.
What a resumable state schema must encode
A schema that only stores data, like the claim amount or the customer's name, tells an agent what it's working on but not where it is in the process.
A few fields are not optional. A workflow ID and current step mark the agent's exact position in the process. Event and decision history records what happened and why, so nothing has to be re-derived by guesswork. Tool call results preserve work that's already been paid for in inference and shouldn't be redone. Retry counters prevent an agent from looping forever on a failing step. Pending actions, each carrying its own timeout, mark what the system is waiting on. Reasoning traces capture the logic behind each decision, so a human or a successor agent can audit the "why," not just the "what".
Every one of those fields maps to a specific failure this architecture is built to prevent.
Atomicity matters just as much as which fields exist. When multiple agents, or an agent and a human, can modify the same state at once, a flat JSON blob invites silent overwrites.
Human-in-the-loop cases make the pending-obligations requirement concrete. Leave any of those three out: the "pause" has no defined way back.
All of this exists for a reason beyond tidiness: observability. If every LLM call, tool invocation, and state transition is traceable, an engineer can reconstruct what the agent knew at step N and why it took action X. Without that trace, debugging a failed agent run turns into forensic guesswork.
State machine semantics: why the shape of allowed transitions matters as much as the fields
Fields describe what an agent knows. Transitions describe what an agent is allowed to do next, and that is where a schema becomes a behavioral contract rather than a passive record.
A paper from August 2026, AgentR, gives a concrete picture of what that contract looks like in practice. Built as a stateful, recovery-aware, and auditable software architecture for LLM-based workflows, it was instantiated through an academic literature-review use case, storing per-paper analytical output as typed persistent entities in PostgreSQL, governed by a six-state ProcessingStatus finite automaton.
Four properties fall out of that design. The system is observable, so any client can query the current state at any time. It's durable, persisted in PostgreSQL rather than sitting in a worker's memory where a crash would erase it. And it's auditable, with every state transition timestamped and traceable through a BackgroundJob table.
The recoverable property carries the most weight here. Building the re-entry transition into the automaton turns the same "terminal" state into a waypoint instead of a wall.
The A2A protocol formalizes a close cousin of this pattern at the protocol layer. Streaming updates run over SSE, push notifications can alert external systems, and a paused task resumes through SubscribeToTask, while GetTask handles polling or retrieving a final result.
If a schema doesn't name its failure states and the transitions leading out of them, failure quietly becomes terminal by default. There's no path back without someone manually restarting the whole process. Naming the states an agent can be in, and naming exactly which transitions are legal from each one, is what turns a schema from a description of data into an enforceable rule about what the agent is permitted to do next.
Checkpointing Around Side Effects
A schema that correctly encodes execution position still isn't safe to resume from, if checkpoints are placed without regard for side effects. Get the placement wrong, and resumability turns from a recovery mechanism into a generator of duplicate actions.
The dangerous case is specific: the checkpoint lied because of where it sat in the sequence.
The safer pattern checkpoints on both sides of a side effect, before it and after it, and pairs that with idempotency keys on every external call. Worker leases add a second layer of protection: they stop a second worker from picking up a task that a crashed worker was still mid-execution on, which matters because without a lease, two workers can end up resuming the same workflow at the same time.
A real-world shape of this discipline shows up in the bex.co incident investigation pattern, where a coding agent investigates an application, an operations agent assesses the cluster, and a human authorizes the rollback. No agent in that chain ever receives another agent's credentials, and auditability is built into the state structure itself rather than bolted on afterward. That separation of authority is itself a side-effect control: no single agent can trigger an irreversible action alone.
Idempotency isn't a nice-to-have for performance. A workflow that can duplicate a payment on resume isn't resumable in any meaningful sense, no matter how cleanly its schema tracks execution position.
The July 2026 MCP statelessness revision: moving state ownership from protocol to schema
In July 2026, MCP removed session-level state from the protocol layer entirely. Cross-call state now moves through explicit, server-minted handles passed as ordinary tool arguments. That change in where the burden of state management sits is worth understanding in detail.
Before the revision, the initialize handshake combined with an Mcp-Session-Id header, issued by the server, pinned a client to one specific server instance. That pinning let some execution state live implicitly inside the session itself, without any application code having to manage it. After the revision, every request carries its own protocol version, client info, and capabilities in a _meta field on the request, and the session concept disappears from the protocol layer altogether.
What that means for schema design is direct: state that used to live implicitly in the MCP session now has to be owned explicitly, either by the calling agent or by an external store. This isn't a refactor teams can defer. The specification itself mandates the shift. Work that used to be the protocol's problem is now the schema's problem.
The governance context around this change signals it's not a temporary draft. Both MCP and A2A now sit under Linux Foundation governance, MCP through the Agentic AI Foundation and A2A as a separate Linux Foundation project. Decisions made at that level tend to hold.
Teams that built on MCP before July 2026 and leaned on session persistence as a shortcut for managing state now have a hole in their architecture, and the only thing that fills it is a schema designed to own that state explicitly. The protocol's retreat from statelessness-as-a-feature is, in effect, the field confirming where state ownership belongs: not in the transport layer, but in the schema that the agent itself carries forward.
What stateful handoffs require the schema to freeze
Handing control from one agent to another, or from an agent to a human and back, is just another form of interruption. The schema has to encode not only where execution is, but which choices are already locked in, so the agent picking up the work can't undo progress that's already been accepted or repeat an action that's already taken effect.
A 2026 arXiv paper on Commitment-Frontier Residual Completion, or CFRC, gives this idea a name: the commitment frontier. It's the exact point in a workflow where three things are simultaneously true. And some obligations remain open, like a receipt that hasn't been sent yet.
The invoice example makes the stakes concrete. A successor agent taking over at that frontier cannot restart the process, because issuing another payment call would create a duplicate charge. It cannot switch invoices, because the user already confirmed INV-42 specifically. And it cannot declare the job done, because the receipt still hasn't gone out. All three constraints come from the same frozen moment in the schema.
Together, they stop a successor agent from acting before it has actually verified what's already settled.
What this requires of the schema is a frozen "residual contract" at every handoff point: what's accepted, what's already realized, and what's still open. A transcript of prior steps doesn't do this job. A successor reading a transcript still has to infer what's fixed and what's still negotiable, and that inference is exactly where handoffs go wrong. The same logic carries over to human-in-the-loop pauses: when an agent stops for human approval, the schema needs to specify what the human is being asked to authorize, what happens if they say no, and what the timeout behavior looks like if they never respond.
Memory architecture: why expanding context windows do not substitute for persistent state
If a model can hold an enormous amount of context, building a separate state schema seems unnecessary. Just append the full history and let the model read its way back to where it left off.
But even a very large context window doesn't solve the same problem a state schema solves, and the answer breaks into four parts.
Context is ephemeral. It clears when a session ends, while a schema persists across sessions and across process restarts. And governance requirements, like deletion, access control, and audit logs, simply can't be satisfied by a context window. Those require structured external storage, because a context window has no concept of "delete this record" or "restrict who can read it."
The common response to this tradeoff organizes memory into three tiers. Long-term persistent store holds cross-session knowledge, user preferences, and learned workflows, kept in vector and graph storage.
None of that tiering helps unless the schema makes the boundaries explicit. The agent needs to know, at any given moment, which tier it's reading from and which tier it's writing to. If that stays implicit, the agent degrades silently the moment its context gets cleared, with no warning that it just lost access to something it needed.
Storage backend choice
Picking a storage backend isn't a deployment detail to settle after the schema is designed. It locks in consistency guarantees, queryability, and how debuggable the system will be, and reversing that choice once agents are running in production gets expensive fast.
Three patterns dominate current practice, each with its own tradeoffs. A relational or document database, PostgreSQL or MongoDB, gives strong consistency, transactional integrity, and real queryability. That makes it the strongest fit for high-concurrency systems managing many agents at once, though it comes with real schema management overhead. A vector database, Pinecone or Milvus, is built for knowledge-intensive agents that need semantic recall from past context; procedural state tracking, things like loop iteration counts or retry counters, needs exact values, so semantic similarity search isn't suited to it.
LangGraph's checkpointing layer shows what the relational approach looks like in practice: every super-step produces a serializable state snapshot that can be written to PostgreSQL, SQLite, Redis, or other supported backends. That snapshot-per-step model is itself a schema decision, not just an engineering convenience. It ties the granularity of recovery to the granularity of the super-step: the backend choice and the schema's definition of a "step" end up determining each other.
None of these three patterns is wrong in the abstract. Each commits a system to a different set of guarantees, and the right one depends on whether the workload is concurrency-heavy, cost-sensitive, or semantic-recall-heavy. What doesn't change across any of them is the underlying requirement this entire piece has been building toward: a schema that names position, obligations, and transitions precisely enough that interruption, whatever form it takes, is just another state the system already knows how to handle.
Sources
- AI Agent Workflow State Persistence: Best Practices 2026
- Building Persistent AI Agents: A Dev's Guide to State Management and Long-Running Workflows - DEV Community
- Do Not Restart: Residual Completion for Stateful Agent Handoffs
- AgentR A Stateful and Recovery-Aware Software Architecture for LLM-based Auditable Workflows
- The 2026-07-28 Specification
- LangGraph Tutorial (2026): Stateful, Controllable LLM Agents


