LangGraph agents finally got a dependable way to keep their state after weeks of silent data loss. After three failed checkpointing tricks—SQLite, raw object storage, and a broken version of each—the author landed on an atomic-update pattern that stops agents from restarting from scratch every time a request arrives.

Why checkpointing matters for LangGraph

LangGraph lets developers stitch together LLM calls into reusable “agents” that can remember what happened earlier in a conversation. Those agents break a user request into sub-tasks, store the intermediate results, and resume where they left off on the next call. If the stored state disappears, the agent recomputes everything, wasting compute, raising latency, and delivering a poor user experience. In a production bot handling Telegram messages, the loss erased weeks of conversation history.

The first fix: SQLite saver

The built-in SqliteSaver works fine when a single instance runs the agent. It writes each checkpoint as a JSON blob in a local SQLite file. Trouble started when the developer added a new field to the AgentState type and redeployed. Existing checkpoints, created before the schema change, lacked the new field. Because SqliteSaver never runs a migration, LangGraph loaded the incomplete JSON, dropped the missing data, and the agent restarted from the beginning.

Key point: SQLite storage is a demo tool, not a production-ready solution when schema evolution is required.

The second fix: Object storage

To gain control over the serialization format, the author wrote a custom saver that uploaded the JSON checkpoint to Oracle Cloud Object Storage. The move gave flexibility to version the schema manually, but it introduced a new failure mode. When two requests hit the same conversation thread simultaneously, both tried to overwrite the same object. Object storage services are optimized for write-once, read-many patterns; they don’t provide atomic overwrite semantics. The race condition produced malformed or truncated JSON files, and the agent again lost its context.

Key point: Plain overwrites in object storage are not safe when multiple workers can touch the same key at the same time.

The third fix: Atomic updates with versioning

The final, stable design combines two ideas: explicit version numbers and conditional writes based on the object’s ETag (the storage service’s checksum identifier).

  1. Read the current checkpoint and capture its ETag.
  2. Increment a version field inside the checkpoint envelope.
  3. Write the updated checkpoint using a conditional request that succeeds only if the ETag matches the one read earlier.
  4. Retry the whole read-increment-write loop if the conditional write fails because another process changed the object.

Because the write succeeds only when no other process has altered the file, only one worker can commit a new state at a time. The version field also makes it easy to detect stale checkpoints and to migrate them forward when the schema changes.

The pattern works with object storage that supports ETag-based conditional writes.

Lessons for AI engineers

  • Use SQLite only for prototypes. Production agents need a store that can handle schema changes and concurrent writes.
  • Plan schema migrations yourself. Typed dictionaries describe shapes for static analysis but don’t enforce runtime structure.
  • Treat state as a shared resource. Concurrency bugs show up as silent data loss; they’re harder to debug than outright exceptions.
  • Use cloud primitives. ETag-based conditional writes give cheap optimistic locking without a separate lock service.
  • Log every step. Silent failures—like a missing field that LangGraph ignores—are the toughest to track down.

What’s next for LangGraph checkpointing?

For teams that have already hit the same roadblocks, the atomic-update recipe offers a quick, low-cost fix. It shows that a reliable production pipeline doesn’t require a heavyweight state store—just careful handling of concurrency and versioning.

Takeaway: A simple versioned envelope plus conditional writes turns a flaky system into a reliable one, letting AI engineers focus on agent logic rather than endless data-loss debugging.