Checkpoint & Resume diagramJob, Worker A, Checkpoints, Worker B, Database, Done. Step captions follow the diagram.JobWorker ACheckpointsWorker BDatabaseDoneCheckpoint & Resume diagramJob, Worker A, Checkpoints, Worker B, Database, Done. Step captions follow the diagram.JobWorker ACheckpointsWorker BDatabaseDone

All steps

Crash and resume

Paused for approval

Parts of this pattern
Job Input / output
The request that starts a long run: here, 'migrate 4 million customer rows to the new schema, 100,000 at a time' (40 steps).
Worker A Agent
The agent process running the job: it plans each step, calls the database tool, and checkpoints after every step.
Checkpoints Memory
A durable store holding the run's state after every step: messages, tool results and the step counter.
Worker B Agent
A fresh process that picks the run up from its last checkpoint, with the full history, and carries on.
Database Tool
The migration target. Each write carries an idempotency key, so a step replayed after a crash does not copy rows twice.
Done Input / output
The finished run: every batch migrated once, with a summary of what was done.
Job → Worker A
The job starts a new run with a stable run id.run_id=mig-0412. Goal: migrate customers_v1 to customers_v2 in batches of 100,000 rows.
Worker A → Databasestep
Each step is one tool call carrying an idempotency key made from the run id and step number; its result is added to the run's state.copy_batch(offset=2,100,000, limit=100,000, key='mig-0412/step-22') -> ok: 100,000 rows copied (2.1 s)
Worker A → Checkpointscheckpoint
After every step the full state is written to the store, before the next step starts.checkpoint mig-0412 v22: step=22, rows_done=2,200,000, messages=47
Checkpoints → Worker Bresume
A new process loads the latest checkpoint and continues from the step after it, with the full history.load mig-0412 v22: resume at step 23 of 40
Worker B → Databasenext steps
The resuming worker runs the remaining steps. Each call carries its step's idempotency key, so a step already applied before the interruption is skipped, not run twice.copy_batch(offset=2,200,000, key='mig-0412/step-23') -> already applied, skipped
Worker B → Done
The new worker runs the remaining steps against the same database, checkpointing as before, then reports what the run did.Done: 4,000,000 rows migrated in 40 steps; 1 restart (worker A killed at step 23).

← → neighboursesc atlas

Reliability & Runtime

Checkpoint & Resume

Also known as Durable execution · Checkpointing · Persistence · Interrupt and resume · Time travel

Save the agent's state after every step, so a crash or a long pause resumes from the last checkpoint instead of starting over.

No single inventor · see source

No single inventor. Durable execution comes from workflow engines such as Temporal and Azure Durable Functions; LangGraph's checkpointers brought it to LLM agents. The year is LangGraph's first PyPI release, 8 January 2024.

Measured over one run

Nodes
6. Boxes in the diagram: models, tools, stores, people and plain code.
LLM calls
0. Model invocations in the first scenario: each time a model or agent node starts thinking, plus each branch it decides.
Tool calls
4. Messages sent to a tool node in the first scenario.
Steps
6. Steps in the first scenario, with repeated steps counted every time they run.
Scenarios
2. Distinct example runs you can switch between on the diagram.
Loop
yes. Whether the flow cycles back on itself until a condition is met.
Parallel
no. Whether two or more messages are in flight at the same time.
Branch
no. Whether the flow takes one path out of several, chosen at run time.
Human in the loop
no. Whether a person appears as a node, to approve, correct or answer.
Autonomy
medium. How much the model decides the control flow itself, from fixed code paths (low) to open-ended (high).
Cost
low. Relative token spend per request.
Latency
medium. Relative wall-clock time per request.

Counted from the first scenario's timeline when the site is built.

Problem

Agents increasingly run for minutes, hours or days: migrating a database in batches, working through a research plan, or waiting for someone to approve a risky step. Processes do not live that long reliably. Deploys restart them, machines are replaced, and a pause for a human’s answer can outlast any request timeout. If the agent’s state lives only in memory, a crash at step 23 of 40 means starting again at step 1, paying for every model call twice and, worse, repeating side effects such as copying rows or sending emails.

How it works

The job starts a run with a stable run id. Worker A executes it one step at a time: the model picks the next action, the worker calls the database, and the result is added to the run’s state. After every step, before the next one begins, the whole state (messages, tool results and the step counter) is written to a durable checkpoint store.

In the example, worker A is killed during step 23. Nothing is lost except that step. Worker B, a fresh process, loads the step-22 checkpoint and continues from step 23 with the full history, as if nothing had happened. Because step 23 may have half-run before the crash, every side-effecting call carries an idempotency key built from the run id and step number, so redoing it cannot copy the same rows twice. The run finishes and reports to done.

The same mechanism handles deliberate pauses. When the run needs a person’s sign-off, it saves a checkpoint marked as waiting and the process simply exits. Days later, the approval loads the checkpoint on whichever worker is free.

Workflow engines such as Temporal take this further by recording every step’s result in an event history and replaying the code against it; agent frameworks such as LangGraph save a snapshot of the graph state after each step. Both give the same guarantee: completed work is never redone.

When to use

  • Runs are long, from minutes to days, and will outlive a deploy or a machine.
  • Steps are expensive or have side effects that must not repeat.
  • The run waits on people or external events: approvals, replies, scheduled times.

When to avoid

  • Calls are short and stateless. If the whole run takes ten seconds, retrying from scratch is simpler and cheaper.
  • Nothing the agent does has side effects, and recomputing is cheap.
  • You cannot make tool calls idempotent. Checkpoints alone will not stop a half-finished step from repeating its effect.

Trade-offs

Every step pays for a write to the store, and the state has to be serializable, which rules out holding open connections or in-memory objects across steps. In exchange, failures cost one step instead of the whole run, pauses become free, and the history of checkpoints doubles as an audit log you can inspect or replay. The real work is designing steps so they can safely run twice.

Failure modes

  • Duplicate side effects: a step that ran just before the crash runs again on resume. Give every external write an idempotency key, or check before writing.
  • Two workers, one run: a slow worker comes back after another has taken over, and both advance the run. Version checkpoints and reject stale writes.
  • State bloat: the full message history is saved every step and grows without bound. Trim or summarize old messages, and store large tool outputs by reference.
  • Code drift: a run paused for days resumes under a new code version that reads the old state differently. Version the state format and migrate it on load.

Build it with your AI

Paste this into Claude Code, Cursor, ChatGPT or any AI coding assistant.

Implement the Checkpoint & Resume pattern in this codebase, using the LLM client and language we already use.

## Goal

Run a long, multi-step agent so that its full state is saved after every step and any process can resume the run from the last checkpoint, without repeating steps that already had side effects.

## How it works

1. Give every run a stable run id. Model the run as numbered steps, and keep its state (messages, tool results, current step, status) in one serializable object.
2. On start, load the latest checkpoint for the run id from a durable store (a database table, not process memory). If there is none, create the initial state.
3. For each step, call the model with the Step prompt, filling in the goal, the completed steps from the state and the latest tool result, and run the tool call it asks for.
4. Pass every side-effecting tool call an idempotency key built from the run id and step number, so a step that is retried after a crash does not apply twice.
5. After the step finishes, append its result to the state and write the new checkpoint (state plus step counter) atomically, with a version check, before starting the next step.
6. When the run must wait for a person or an event, save a checkpoint with status waiting and exit the process; a later request with the run id loads it and continues.

## Prompts

### Step prompt

```markdown
You are carrying out a long task one step at a time. The run may have been
paused or restarted; the completed steps below are the source of truth.

<goal>{{goal}}</goal>
<completed_steps>
{{completed_steps}}
</completed_steps>
<last_result>{{last_tool_result}}</last_result>

Decide the single next step and call one tool to do it.
Never redo a step listed as completed.
If the goal is fully done, reply with DONE and a one-paragraph summary.
```

## Stop rule

Stop when the model reports the goal is complete, or after a step cap (default 60). On a crash, nothing is returned: the run stays in the store and a supervisor restarts it on another worker. If a step fails 3 times, mark the run failed with its last checkpoint.

## Requirements

- Write checkpoints to durable storage with a version number per run, and reject a write whose version is stale so two workers cannot advance the same run.
- Make every external write idempotent with the run-and-step key, or check before writing; never rely on a step running exactly once.
- Keep old checkpoints for a retention window so a run can be inspected or replayed from any earlier step.
- Log each checkpoint write with the run id, step number, worker id and size.
- Add a test with a stub LLM and a fake tool where the process raises after step 2's checkpoint; restart with the same run id and assert the fake tool received steps 1 and 2 exactly once each and the run completes from step 3.
- Add a second test where the process raises after step 3's tool call but before its checkpoint; restart and assert the fake tool received key 'run/step-3' twice but applied it once (its row count is unchanged), and the run completes.

Prompt templates

Step prompt
You are carrying out a long task one step at a time. The run may have been
paused or restarted; the completed steps below are the source of truth.
<goal>{{goal}}</goal>
<completed_steps>
{{completed_steps}}
</completed_steps>
<last_result>{{last_tool_result}}</last_result>
Decide the single next step and call one tool to do it.
Never redo a step listed as completed.
If the goal is fully done, reply with DONE and a one-paragraph summary.

Related patterns

Composes well with:

Sources

  1. LangGraph docs: Persistence and durable execution
  2. Temporal docs: Understanding Temporal

From the Agentic Atlas by Joran Kikke · Edit on GitHub · Suggest a correction