Skip to main content
Workflow is the core building block in Polos. A workflow is durable code - it survives failures and resumes exactly where it stopped.

What is a workflow?

A workflow is a Python function decorated with @workflow. It receives a WorkflowContext (ctx) and your input data.
Let’s unpack what’s happening here: ctx.step.run("search_web", search_web, input.topic) tells Polos to execute search_web (a regular Python function) as a durable step. If the workflow crashes and replays, completed steps are skipped.

Step: The unit of durability

Steps are how Polos achieves durability. Each step has a unique step key (like "search_web" or "generate_report"). When a workflow replays after a failure, Polos checks which steps already completed and skips them. What should be a step?
  • ✅ External API calls (OpenAI, Stripe, databases)
  • ✅ Non-deterministic operations (LLM calls, time.time(), random())
  • ✅ Side effects (sending emails, charging cards, writing to DB)
Critical rule: Each step in a workflow must have a unique step key. In loops, use variables:

Workflow composition

Workflows can invoke other workflows. The parent suspends while children execute - no compute is consumed during waits.

Waiting

Workflows can pause for time or events. Workers suspend during waits consuming no compute.

Starting workflows

Workflows can be triggered in three ways: 1. Direct invocation
2. Event-triggered
3. Scheduled

Key takeaways

  • Workflows are durable - they survive failures and resume from the last completed step
  • Steps are the unit of durability - use them for API calls, side effects, and non-deterministic operations
  • Step keys must be unique per execution
  • Workers suspend during waits (child workflows, events, timeouts) - no compute consumed

Learn more

For detailed guides on workflows and steps, see:
  • Workflows – Complete workflow reference
  • Steps – Built-in step functions