Agno durable execution vs. Pydantic AI Temporal
Pydantic AI hands a run to an external engine like Temporal or DBOS. Agno checkpoints to the database you already run and resumes in place. What each guarantees, and when you need an engine.
Kaustubh ShuklaSenior Software EngineerOctober 22, 202610 min read
Agno behaviour checked against the library source on 22 October 2026; Pydantic AI behaviour against its durable execution docs the same day.
Agno and Pydantic AI both keep an agent run alive across a crash, but they divide the work differently. Pydantic AI hands the run to an external engine, one of eight including Temporal and DBOS, which recovers it without redoing completed calls. Agno has no engine: it checkpoints to the database you already run and resumes in place. Run a second system, or don't.
| Dimension | Agno | Pydantic AI |
|---|---|---|
| Durability model | Checkpoints in the framework, durable queue in AgentOS | An engine attached as a capability, plus engine-free StepPersistence |
| Extra infrastructure | None beyond your database; Redis optional | Temporal needs a server and workers; DBOS is in-process on Postgres or SQLite |
| Checkpoint granularity | After each tool batch | Each model request and each wrapped tool call, varying by engine |
| Recovery | Explicit: acontinue_run, same run_id | Temporal: automatic replay, skipping completed activities |
| Replica or worker crash | Lease expires, another replica starts the run over | Another worker replays the workflow |
| Side-effect safety | None built in; make tools idempotent | A ledger flags calls left in an unknown state |
| Temporal integration | None | Native |
What does "durable execution" mean for an agent?
Pydantic AI's own docs draw the line better than most, under a heading called "Durability is not storage":
A durable engine keeps one run alive when it crashes partway through a step, with retries and journaled model and tool calls. Saving a run, resuming it later and forking it from an earlier step need no engine.
Those are two separate capabilities, and conflating them is where most comparisons go wrong.
Agno does the second and not the first. It saves runs, resumes them, and forks them, and its runtime adds a durable queue so an accepted run survives a disconnect or a deploy. What it does not have is an engine that notices a crash mid-step and recovers it for you.
So the real question is not "which is more durable". It is whether you want recovery to happen on its own, and what you will run to get that.
How does Pydantic AI use Temporal?
You attach durability to the agent as a capability and define a workflow around it:
agent = Agent('openai:gpt-6.1-sol', name='geography', capabilities=[TemporalDurability()])
@workflow.defn
class GeographyWorkflow(PydanticAIWorkflow):
__pydantic_ai_agents__ = [agent]
@workflow.run
async def run(self, prompt: str) -> str:
return (await agent.run(prompt)).output
client = await Client.connect('localhost:7233', plugins=[PydanticAIPlugin()])Temporal journals each model request and each wrapped tool call. When a worker dies, another picks the workflow up and replays its history, skipping what already finished. That is the capability Agno does not have, and it is a real one.
It comes with replay constraints, because determinism is what makes replay work: stable, unique activity names, Pydantic-serializable dependencies, a 2MB default payload cap, limited RunContext inside tools, buffered rather than real-time streaming, no BinaryImage output, async only, and history changes that need draining or worker versioning.
Note also that TemporalAgent and DBOSAgent are on the way out, to be removed in v3 in favour of the capability form above.
What are Pydantic AI's options without Temporal?
Eight engines, which is the part people miss when they treat this as a Temporal question. Temporal, DBOS, Prefect, Restate, AWS Lambda, Absurd, pgtask and Apache Airflow, plus a builder for anything else. Only one engine per agent; attaching a second raises UserError.
DBOS is the one worth knowing about if the objection is operational rather than technical, because it runs fully in-process as a library on Postgres or SQLite, with no server to stand up:
from dbos import DBOS
from pydantic_ai import Agent
from pydantic_ai.durable_exec.dbos import DBOSDurability
DBOS(config={'name': 'pydantic_dbos_agent', 'system_database_url': 'sqlite:///dbostest.sqlite'})
agent = Agent('openai:gpt-6.1-sol', name='geography', capabilities=[DBOSDurability()])
@DBOS.workflow()
async def answer(question: str) -> str:
return (await agent.run(question)).outputOne catch to know: function tools are not checkpointed under DBOS unless you decorate them with @DBOS.step. The guarantee depends on the engine, not just on having one.
And below the engines there is StepPersistence in Pydantic AI Harness, which snapshots each settled tool step to a store of your choosing. Resume is explicit, and its docs say plainly that automatic execution recovery is not implemented. That tier is the closest comparison to what Agno does.
How does Agno recover a crashed run?
Set checkpoint="tool-batch" and the run is saved after each tool batch rather than only at the end:
from agno.agent import Agent
from agno.db.postgres import PostgresDb
from agno.models.openai import OpenAIResponses
from agno.run.base import RunStatus
db = PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai")
def build_agent() -> Agent:
return Agent(
model=OpenAIResponses(id="gpt-5.6-luna"),
tools=[search, fetch_detail],
db=db,
checkpoint="tool-batch", # the default, "runs", saves only at the end
)
# Process A is killed mid-run: OOM, SIGKILL, a deploy.
await build_agent().arun("Research agno checkpointing", session_id="s1")
# Process B: find the run left RUNNING and resume it in place.
agent = build_agent()
session = agent.db.get_session(session_id="s1", session_type="agent")
crashed = next(r for r in reversed(session.runs) if r.status == RunStatus.running)
resumed = await agent.acontinue_run(run_id=crashed.run_id, session_id="s1")The run continues under the same run_id. Cancelled runs are the exception and raise RunNotContinuableError.
Two things that paragraph of code is quietly telling you. Process B is code you write, where Temporal would have done it for you. And a RUNNING row might belong to a run that is still alive on another worker, so only resume one when you know the process is gone.
Above that sits the durable queue, which is where AgentOS does take care of things on your behalf:
AgentOS(queue=QueueConfig(durable=True))It defaults to off. Turned on, accepted runs are stored in your database, a crashed replica's lease expires after 60 seconds and another replica reclaims the job, and /queue/jobs lists failures with a requeue endpoint behind them. Idempotency-Key deduplicates submissions. The default max_attempts=1 makes it at-most-once, and raising it starts a reclaimed run over from the beginning rather than from its checkpoint.
For disconnects, POST /agents/{id}/runs/{run_id}/resume with last_event_index replays missed events and then joins the live stream, from any replica when Redis is configured.
Agno vs. Temporal for agent orchestration: do you need both?
Agno is not a workflow engine and has no Temporal integration. The code does not mention it.
The difference shows up at the moment of a crash. When a Temporal worker dies, another replays the workflow from history and skips the activities that already finished. When an Agno replica dies, the durable queue hands the run to another replica, which starts it over. To avoid redoing completed tool calls you set checkpoint="tool-batch" and resume in place, which is a thing you do rather than a thing that happens.
Temporal is the stronger choice when you need replayable, versioned workflows spanning services beyond the agent. Agno's position is that you do not have to run one. Both are defensible; they are not the same guarantee.
One correction worth making while we are here: Agno Workflows are not durable workflows in this sense. They pause and resume for human approval, they have no checkpoint setting, and they do not recover from a crash.
Which should you use?
Choose Pydantic AI with an engine if you already operate Temporal, if you want recovery to happen mid-run without you writing it, if you want a choice of eight engines, or if you want the tool-effect ledger that flags calls left in an unknown state after a crash.
Choose Agno if you would rather not run or learn a workflow engine, if checkpoints in the database you already have are enough, if you want a crashed run to resume in place under the same run_id, or if you want queued runs to survive disconnects, deploys and replica crashes without a second system.
Choose DBOS with Pydantic AI if you want engine-grade journaling without a server. It is the honest middle of this comparison, and the option most likely to be overlooked.
If you are weighing the two products more broadly, Agno tracing vs. LangSmith covers the observability side of the same decision.
Sources
- Background execution and scheduling — durable queue, stream resume, lease-based scheduling
- Agno library source, 22 October 2026 —
checkpointvalues and the reserved"tools",acontinue_run,RunNotContinuableError,QueueConfigdefaults - Pydantic AI durable execution — the engine list and "Durability is not storage"
- Temporal and DBOS — setup and constraints
Frequently asked questions
No. There is no Temporal integration in the Agno docs or code. Agno provides its own checkpoints, a durable job queue and a scheduler instead.
Only for TemporalDurability. DBOS runs in-process as a library and checkpoints to Postgres or SQLite, and StepPersistence in Pydantic AI Harness saves and resumes runs without any engine at all.
Yes, if checkpoint="tool-batch" is set. Call acontinue_run or POST /continue and the run continues under the same run_id. A queued run on a crashed replica is picked up by another replica, which starts it over rather than resuming it.
With background execution in AgentOS the run keeps going. The client reconnects to /runs/{run_id}/resume with last_event_index, receives the events it missed, and then joins the live stream. With Redis configured that works from any replica.
They guarantee different things. Temporal recovers on its own by replaying history and skipping calls that already completed. Agno saves state after each tool batch and resumes when you ask it to. Agno's queue never loses an accepted run and is at-most-once by default.
Not in the Temporal sense. Workflows pause and resume for human approval, but they have no checkpoint setting and do not recover from a crash.