--- title: Checkpointing description: Automatically save execution state so crews, flows, and agents can resume after failures. icon: floppy-disk mode: "wide" --- Checkpointing saves a snapshot of execution state during a run so a crew, flow, or agent can resume after a failure or be forked into an alternate branch. How checkpointing works: events, storage, and inheritance. A 5-minute walkthrough: run, interrupt, resume. Task-focused recipes for common workflows. `CheckpointConfig`, events, providers, and CLI. ## Explanation ### What a checkpoint is A checkpoint is a serialized snapshot of `RuntimeState` written at a point in execution. It records which tasks have completed, their outputs, the current inputs, and a lineage ID that identifies the run. When you restore from a checkpoint, CrewAI rebuilds that state, skips already-completed work, and continues. When you fork from one, CrewAI restores the state under a new lineage so the new branch and the original run do not overwrite each other. ### When checkpoints are written Checkpointing is event-driven. The runtime subscribes to events you select via `on_events` and writes a checkpoint each time one fires. The default `task_completed` produces one checkpoint per finished task — a sensible tradeoff between granularity and disk use. Higher-frequency events like `llm_call_completed` are available for fine-grained recovery but write far more files. ### Storage Two providers ship with CrewAI: - `JsonProvider` writes one file per checkpoint. Human-readable and easy to inspect. - `SqliteProvider` writes to a single SQLite database. Better for high-frequency checkpointing. Both prune oldest checkpoints when `max_checkpoints` is set. Checkpoint writes are best-effort. A failed checkpoint is logged but does not interrupt the run. ### Inheritance model `Crew`, `Flow`, and `Agent` all accept a `checkpoint` argument. Children inherit from their parent unless they set their own value or pass `False` to opt out. Enable checkpointing once on the crew and every agent participates, or selectively exclude one agent. ## Tutorial: Resume a failing crew This walkthrough takes ~5 minutes. You will run a two-task crew, kill it midway, and resume from the saved checkpoint. ```python from crewai import Agent, Crew, Task researcher = Agent(role="Researcher", goal="Research", backstory="Expert") writer = Agent(role="Writer", goal="Write", backstory="Expert") crew = Crew( agents=[researcher, writer], tasks=[ Task(description="Research AI trends", agent=researcher, expected_output="bullets"), Task(description="Write a summary", agent=writer, expected_output="paragraph"), ], checkpoint=True, ) ``` ```python result = crew.kickoff() ``` Press `Ctrl+C` after the first task finishes. Look in `./.checkpoints/` — a file named `_.json` is the checkpoint. ```python from crewai import CheckpointConfig result = crew.kickoff( from_checkpoint=CheckpointConfig( restore_from="./.checkpoints/_.json", ), ) ``` The research task is skipped, the writer runs against the saved research output, and the crew finishes. ## How-to guides ```python crew = Crew(agents=[...], tasks=[...], checkpoint=True) ``` Writes to `./.checkpoints/` on every `task_completed`. ```python from crewai import Crew, CheckpointConfig crew = Crew( agents=[...], tasks=[...], checkpoint=CheckpointConfig( location="./my_checkpoints", on_events=["task_completed", "crew_kickoff_completed"], max_checkpoints=5, ), ) ``` ```python JsonProvider from crewai import Crew, CheckpointConfig from crewai.state import JsonProvider crew = Crew( agents=[...], tasks=[...], checkpoint=CheckpointConfig( location="./my_checkpoints", provider=JsonProvider(), max_checkpoints=5, ), ) ``` ```python SqliteProvider from crewai import Crew, CheckpointConfig from crewai.state import SqliteProvider crew = Crew( agents=[...], tasks=[...], checkpoint=CheckpointConfig( location="./.checkpoints.db", provider=SqliteProvider(), max_checkpoints=50, ), ) ``` SQLite enables WAL journal mode for concurrent reads. Prefer it for high-frequency checkpointing. ```python crew = Crew( agents=[ Agent(role="Researcher", ...), Agent(role="Writer", ..., checkpoint=False), ], tasks=[...], checkpoint=True, ) ``` ```python config = CheckpointConfig(restore_from="./my_checkpoints/.json") crew = Crew.from_checkpoint(config) result = crew.kickoff() ``` `fork()` restores a checkpoint under a fresh lineage so the new run does not collide with the original. ```python config = CheckpointConfig(restore_from="./my_checkpoints/.json") crew = Crew.fork(config, branch="experiment-a") result = crew.kickoff(inputs={"strategy": "aggressive"}) ``` The `branch` label is optional; one is generated if omitted. ```python crew = Crew( agents=[researcher, writer], tasks=[research_task, write_task, review_task], checkpoint=CheckpointConfig(location="./crew_cp"), ) ``` Default trigger: `task_completed`. ```python from crewai.flow.flow import Flow, start, listen from crewai import CheckpointConfig class MyFlow(Flow): @start() def step_one(self): return "data" @listen(step_one) def step_two(self, data): return process(data) flow = MyFlow( checkpoint=CheckpointConfig( location="./flow_cp", on_events=["method_execution_finished"], ), ) result = flow.kickoff() config = CheckpointConfig(restore_from="./flow_cp/.json") flow = MyFlow.from_checkpoint(config) result = flow.kickoff() ``` ```python agent = Agent( role="Researcher", goal="Research topics", backstory="Expert researcher", checkpoint=CheckpointConfig( location="./agent_cp", on_events=["lite_agent_execution_completed"], ), ) result = agent.kickoff(messages=[{"role": "user", "content": "Research AI trends"}]) ``` Register a handler on any event and call `state.checkpoint()`. ```python Sync from crewai.events.event_bus import crewai_event_bus from crewai.events.types.llm_events import LLMCallCompletedEvent @crewai_event_bus.on(LLMCallCompletedEvent) def on_llm_done(source, event, state): path = state.checkpoint("./my_checkpoints") print(f"Saved checkpoint: {path}") ``` ```python Async from crewai.events.event_bus import crewai_event_bus from crewai.events.types.llm_events import LLMCallCompletedEvent @crewai_event_bus.on(LLMCallCompletedEvent) async def on_llm_done_async(source, event, state): path = await state.acheckpoint("./my_checkpoints") print(f"Saved checkpoint: {path}") ``` A `state` argument is supplied automatically when the handler takes three parameters. See [Event Listeners](/en/concepts/event-listener) for the full event catalog. ```bash crewai checkpoint # auto-detects .checkpoints/ or .checkpoints.db crewai checkpoint --location ./my_checkpoints crewai checkpoint --location ./.checkpoints.db ``` Checkpoint TUI The left panel groups checkpoints by branch; forks nest under their parent. Selecting a checkpoint shows its metadata, entity state, and task progress. **Resume** continues the run; **Fork** starts a new branch. The detail panel exposes two editable areas: - **Inputs** — original kickoff inputs, pre-filled and editable. - **Task outputs** — outputs of completed tasks. Editing an output and hitting **Fork** invalidates downstream tasks so they re-run against the modified context. Useful for "what if" exploration: fork, tweak, observe. ```bash crewai checkpoint list ./my_checkpoints crewai checkpoint info ./my_checkpoints/.json crewai checkpoint info ./.checkpoints.db ``` ## Reference ### `CheckpointConfig` Storage destination. A directory for `JsonProvider`, a database file path for `SqliteProvider`. Event types that trigger a checkpoint. See [event types](#event-types). Storage backend. Either `JsonProvider` or `SqliteProvider`. Maximum checkpoints to retain. Oldest are pruned after each write. Checkpoint to restore from when passed via `from_checkpoint`. ### `checkpoint` field values Accepted by `Crew`, `Flow`, and `Agent`. Inherit from parent. Enable with defaults. Explicit opt-out. Stops inheritance. Custom configuration. ### Event types Common values for `on_events`: | Use case | Events | |:---------|:-------| | After each task | `["task_completed"]` | | After each flow method | `["method_execution_finished"]` | | After agent execution | `["agent_execution_completed"]`, `["lite_agent_execution_completed"]` | | On crew completion only | `["crew_kickoff_completed"]` | | After every LLM call | `["llm_call_completed"]` | | Everything | `["*"]` | `["*"]` and high-frequency events like `llm_call_completed` write many checkpoints and can degrade performance. Pair them with `max_checkpoints`. ### Storage providers One file per checkpoint, named `_.json` inside `location`. Single database file at `location` with WAL journaling. ### CLI | Command | Purpose | |:--------|:--------| | `crewai checkpoint` | Launch the TUI; auto-detect storage. | | `crewai checkpoint --location ` | Launch the TUI against a specific location. | | `crewai checkpoint list ` | List checkpoints. | | `crewai checkpoint info ` | Inspect a checkpoint file or the latest entry in a SQLite database. |