About This Book
Introduction
- Why agents crash
- The reference agent
- What you will learn
- How to use this book
- The Problem
The reference agent and its baseline
- Why agents die in the wild
- Timeouts and stalled calls
- Rate limits and 429s
- Deploys and OOM kills
- The failure modes in-lab
- What a restart loses
- The ticket agent flow
- The stand-in model and ledger
- Running the baseline lab
- kill -9 after the refund
- Reading ledger.log
Durable execution fundamentals
- Workflows, steps, and activities
- Replay and determinism
- Exactly-once versus at-least-once
- What the engine journals
- Why replay must not re-bill
- Durable Execution with DBOS
DBOS Transact on Postgres
- Postgres as the engine
- Workflows and workflow IDs
- The DBOSDurability capability
- The 3.0 schema break
- Running the DBOS lab
DBOS step tools for tool calls
- Model calls versus step calls
- Wrapping tools with DBOS.step
- dbos-crash and dbos-step-tools compared
- Reading operation_outputs
- Why the refund runs once
Recovering interrupted DBOS runs
- What a crash leaves behind
- How workflow recovery works
- Recovering pending workflows
- Workflow IDs and idempotency
- Upgrading code during recovery
- Operating recovery in production
- Durable Execution with Temporal
Temporal workers and task queues
- The Temporal service and workers
- Workflows versus activities
- Polling task queues
- Event history persistence
- Starting a Python worker
Temporal tool calls as activities
- The TemporalDurability capability
- Tool calls as activities
- The temporal-crash lab
- The in-flight request retried
- Reading the event history
Replay safety in Temporal
- Determinism on replay
- Non-determinism failures
- Safe payload conversion
- Replay-safe tracing
- Replay testing your workflows
- Durability Patterns
Idempotent tools and idempotency keys
- Where double effects come from
- Idempotency keys on tools
- kill -9 during the refund
- Treating calls as retries
- The ledger after recovery
Retries, fallbacks, and replay billing
- Configuring retries per step
- Fallback models and providers
- Honoring Retry-After
- When replay must not re-bill
- Coupling retries to durability
Human-in-the-loop waits
- Why waits break plain agents
- Durable sleep and signals
- Signals in Temporal
- Human approval across a restart
- Approval across a kill -9
Versioning workflows in flight
- When code changes mid-run
- workflow.patched and deprecate_patch
- Worker and task-queue versioning
- Upgrading DBOS workflows
- Versioning the reference agent
Observability across restarts
- Tracing what an agent did
- Spans and events across recoveries
- Replay-safe exporters
- Correlating attempts by run id
- Tracing the crash lab
- Putting It to Work
Crash tests as a CI suite
- Kill points as pytest tests
- Recovering with a fresh process
- Asserting the refund occurs once
- Ledger counts after recovery
- DBOS step-name checks
- Temporal replay tests
- Regressions the suite catches
- A CI job
Retrofitting an existing agent, end to end
- The retrofit roadmap
- DBOSDurability capability first
- Tools as DBOS steps
- Adding the idempotency key
- Adding tracing
- The Temporal upgrade path
- From double to single refund
- Replaying both histories
- Alternatives and Decisions
The Restate option
- Restate’s virtual objects
- Durable steps in Python
- Restate with pydantic-ai
- Recovery and journaling model
- Running the Restate lab
The Prefect option
- Flows, tasks, and results
- Result persistence and retries
- Resuming a crashed flow
- The Prefect durability capability
- Running the Prefect lab
Choosing your durability stack
- What each engine journals
- When files-plus-resume is enough
- Comparing Restate, Inngest, Hatchet
- Cost of complexity versus guarantees
- Decision guide for your agent
Conclusion
- What the lab proved
- What you can now build
- Where to go next
Appendix A: LangGraph checkpointers
- What a checkpointer is
- Backends
- The saver interface
- Durability modes
- Recovery by thread_id
- Interrupts and approval
- What a checkpointer does not do
- Between LangGraph and the engines
Appendix B: OpenAI Agents SDK sessions
- What a session is
- The Session protocol
- Built-in backends
- Retrieval and compaction
- The durability boundary
- Sessions and human approval
- What to reach for instead
Appendix C: The lab code
- The container
- ticket.py
- dbos_app.py
- temporal_app.py
- history.py
- test_crashes.py
- test_replay.py
- provider_api.py
- tracing.py
- prefect_app.py
- restate_app.py