What is @persist?
@persist layers durable checkpoints underneath Flow execution. Applied at class scope, it captures Flow state so you can resume after process crashes, deploys, or human delays; applied at method scope, it snapshots after specific milestones such as finishing an expensive LLM call or receiving a webhook. The framework assigns a state identifier you thread back into kickoff to continue exactly where the graph left off.
SqliteProvider is the pragmatic default for single-region services, while JsonProvider or custom StorageBackend implementations help when compliance wants object-store artifacts or when you need cross-region replication. CheckpointConfig wires the backend alongside retention knobs — tune it when flows emit large intermediate payloads so databases do not grow without compaction policies.
Treat persisted state as part of your security boundary: it often includes prompts, tool outputs, and PII from human reviewers. Encrypt at rest where the backend allows, redact fields you do not need for resume, and expire checkpoints when tickets close so dormant sessions do not leak stale secrets.
When to Use
Long-running flows, HITL flows, anything that must survive a crash.
Use Cases
- • Long-running flows
- • HITL wait states
- • Distributed execution
Key Features
- ✓ Class- or method-scoped
- ✓ Pluggable storage
- ✓ Automatic state IDs
When NOT to Use
Short, stateless tests where persistence adds noise.
Notes
Serialization constraints
State must round-trip through your provider. Open sockets, live clients, or ORM sessions belong outside persisted fields — store identifiers and rehydrate on resume.
Checkpoint growth
High-frequency persists on chatty loops inflate storage. Prefer persisting after coarse milestones or diff large blobs to object storage with references in Flow state.
Concurrency
Two workers resuming the same state ID can double-apply effects. Gate resumes with leases, version counters, or single-active-consumer queues at the orchestration layer.
Human-feedback pairing
Human gates may pause for hours. Persist before awaiting feedback so restarts do not replay paid LLM steps or duplicate outbound emails tied to the same ticket.
Import
from crewai.flow.persistence import persist
How to Apply
@persist()
class MyFlow(Flow[MyState]):
...
What It Enables
- ✓ Resumability
- ✓ Crash recovery
- ✓ Long-running workflows
Code Examples
Whole-flow
@persist()
class MyFlow(Flow):
@start()
def begin(self):
...
Method-scoped checkpoint
class BillingFlow(Flow):
@start()
def load_invoice(self):
return self.state.invoice_id
@persist()
@listen(load_invoice)
def charge(self, invoice_id):
return payments.charge(invoice_id)
JsonProvider with CheckpointConfig
from crewai.flow.flow import Flow, start
from crewai.state.checkpoint_config import CheckpointConfig, persist
from crewai.state import JsonProvider
@persist(config=CheckpointConfig(storage=JsonProvider()))
class AuditedFlow(Flow):
@start()
def begin(self):
return 'checkpointed'
Integration Patterns
SqliteProvider (default)
JsonProvider
Custom StorageBackend
Common Mistakes
❌ Persisting an in-memory dict that contains unpicklable objects
✅ Use a Pydantic state model with serializable fields.
Related: Task class reference, Agent class reference, and the first Crew tutorial.
@persist FAQ
What is @persist in CrewAI?
Persists Flow state to a backend store (SQLite by default) so the flow can be resumed. @persist layers durable checkpoints underneath Flow execution. Applied at class scope, it captures Flow state so you can resume after process crashes, deploys, or human delays; applied at method scope, it snapshots after specific milestones such as finishing an expensive LLM call or receiving a webhook. The framework assigns a state identifier you thread back into kickoff to continue exactly where the graph left off. SqliteProvider is the pragmatic default for single-region …
Which module defines the CrewAI decorator @persist?
DevShelfHub maps @persist to Python module crewai.flow.persistence. Pin your installed crewai version and match imports to the import snippet on this page.
When should I use @persist?
Long-running flows, HITL flows, anything that must survive a crash.
When should I avoid @persist?
Short, stateless tests where persistence adds noise.
How do I apply @persist in Python?
@persist() class MyFlow(Flow[MyState]): ...
Where can I explore more CrewAI API reference pages?
Open the CrewAI API reference index on DevShelfHub to search classes, methods, and decorators, each with runnable examples, parameters, common mistakes, and cross-links.