# Save Parallel Workflow Steps (/examples/components/workflows/save-parallel-steps)



Demonstrates creating a workflow with parallel steps, saving it to the database, and loading it back.

Apply the setup adjustment below before saving: the current source omits an explicit model on the research agents, so their tools are not serialized. Reloading executable tools also requires their toolkits in a `Registry`.

```python title="save_parallel_steps.py"
"""
Save Parallel Workflow Steps
============================

Demonstrates creating a workflow with parallel steps, saving it to the
database, and loading it back.
"""

from agno.agent import Agent
from agno.db.postgres import PostgresDb
from agno.tools.hackernews import HackerNewsTools
from agno.tools.websearch import WebSearchTools
from agno.workflow.parallel import Parallel
from agno.workflow.step import Step
from agno.workflow.workflow import Workflow, get_workflow_by_id

# ---------------------------------------------------------------------------
# Setup
# ---------------------------------------------------------------------------
# Database
db_url = "postgresql+psycopg://ai:ai@localhost:5532/ai"
db = PostgresDb(db_url=db_url)

# ---------------------------------------------------------------------------
# Create Agents
# ---------------------------------------------------------------------------
# Agents
hackernews_researcher = Agent(
    name="HackerNews Researcher",
    instructions="Research tech news and trends from Hacker News",
    tools=[HackerNewsTools()],
)

web_researcher = Agent(
    name="Web Researcher",
    instructions="Research general information from the web",
    tools=[WebSearchTools()],
)

writer = Agent(
    name="Content Writer",
    instructions="Write well-structured content from research findings",
)

reviewer = Agent(
    name="Content Reviewer",
    instructions="Review and improve the written content",
)

# ---------------------------------------------------------------------------
# Create Workflow Steps
# ---------------------------------------------------------------------------
# Steps
research_hn_step = Step(
    name="ResearchHackerNews",
    description="Research tech news from Hacker News",
    agent=hackernews_researcher,
)

research_web_step = Step(
    name="ResearchWeb",
    description="Research information from the web",
    agent=web_researcher,
)

write_step = Step(
    name="WriteArticle",
    description="Write article from research findings",
    agent=writer,
)

review_step = Step(
    name="ReviewArticle",
    description="Review and finalize the article",
    agent=reviewer,
)

# ---------------------------------------------------------------------------
# Create Workflow
# ---------------------------------------------------------------------------
# Workflow
workflow = Workflow(
    name="Parallel Research Pipeline",
    description="Research from multiple sources in parallel, then write and review",
    steps=[
        Parallel(
            research_hn_step,
            research_web_step,
            name="ParallelResearch",
            description="Run HackerNews and Web research in parallel",
        ),
        write_step,
        review_step,
    ],
    db=db,
)

# ---------------------------------------------------------------------------
# Run Workflow Example
# ---------------------------------------------------------------------------
if __name__ == "__main__":
    # Save
    print("Saving workflow...")
    version = workflow.save(db=db)
    print(f"Saved workflow as version {version}")

    # Load
    print("\nLoading workflow...")
    loaded_workflow = get_workflow_by_id(db=db, id="parallel-research-pipeline")

    if loaded_workflow:
        print("Workflow loaded successfully!")
        print(f"  Name: {loaded_workflow.name}")
        print(f"  Steps: {len(loaded_workflow.steps) if loaded_workflow.steps else 0}")

        # Uncomment to run the loaded workflow
        # loaded_workflow.print_response(input="Latest developments in AI agents", stream=True)
    else:
        print("Workflow not found")
```

## Run the Example [#run-the-example]

<Steps>
    <Step title="Set up your virtual environment">
      <CodeBlockTabs defaultValue="Mac">
        <CodeBlockTabsList>
          <CodeBlockTabsTrigger value="Mac">
            Mac
          </CodeBlockTabsTrigger>

          <CodeBlockTabsTrigger value="Windows">
            Windows
          </CodeBlockTabsTrigger>
        </CodeBlockTabsList>

        <CodeBlockTab value="Mac">
          ```bash
          uv venv --python 3.12
          source .venv/bin/activate
          ```
        </CodeBlockTab>

        <CodeBlockTab value="Windows">
          ```bash
          uv venv --python 3.12
          .venv\Scripts\activate
          ```
        </CodeBlockTab>
      </CodeBlockTabs>
    </Step>

  <Step title="Install dependencies">
    ```bash
    uv pip install -U agno "psycopg[binary]" ddgs fastapi openai sqlalchemy
    ```
  </Step>

  <Step title="Export your OpenAI API key">
    <CodeBlockTabs defaultValue="Mac/Linux">
      <CodeBlockTabsList>
        <CodeBlockTabsTrigger value="Mac/Linux">
          Mac/Linux
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="Windows">
          Windows
        </CodeBlockTabsTrigger>
      </CodeBlockTabsList>

      <CodeBlockTab value="Mac/Linux">
        ```bash
        export OPENAI_API_KEY="your_openai_api_key_here"
        ```
      </CodeBlockTab>

      <CodeBlockTab value="Windows">
        ```bash
        $Env:OPENAI_API_KEY="your_openai_api_key_here"
        ```
      </CodeBlockTab>
    </CodeBlockTabs>
  </Step>

    <Step title="Run PgVector">
      <CodeBlockTabs defaultValue="macOS / Linux">
        <CodeBlockTabsList>
          <CodeBlockTabsTrigger value="macOS / Linux">
            macOS / Linux
          </CodeBlockTabsTrigger>

          <CodeBlockTabsTrigger value="Windows">
            Windows
          </CodeBlockTabsTrigger>
        </CodeBlockTabsList>

        <CodeBlockTab value="macOS / Linux">
          ```bash
          docker run -d \
            -e POSTGRES_DB=ai \
            -e POSTGRES_USER=ai \
            -e POSTGRES_PASSWORD=ai \
            -e PGDATA=/var/lib/postgresql \
            -v pgvolume:/var/lib/postgresql \
            -p 5532:5432 \
            --name pgvector \
            agnohq/pgvector:18
          ```
        </CodeBlockTab>

        <CodeBlockTab value="Windows">
          ```powershell
          docker run -d `
            -e POSTGRES_DB=ai `
            -e POSTGRES_USER=ai `
            -e POSTGRES_PASSWORD=ai `
            -e PGDATA=/var/lib/postgresql `
            -v pgvolume:/var/lib/postgresql `
            -p 5532:5432 `
            --name pgvector `
            agnohq/pgvector:18
          ```
        </CodeBlockTab>
      </CodeBlockTabs>
    </Step>

  <Step title="Preserve research tools across save and load">
    Add `from agno.models.openai import OpenAIResponses` to the imports. After constructing the agents and before `workflow.save(...)`, set their models:

    ```python
    hackernews_researcher.model = OpenAIResponses(id="gpt-5.6-luna")
    web_researcher.model = OpenAIResponses(id="gpt-5.6-luna")
    ```

    Add `from agno.registry import Registry` and create this registry before loading:

    ```python
    registry = Registry(tools=[HackerNewsTools(), WebSearchTools()])
    ```

    Add `registry=registry, strict=True` to `get_workflow_by_id(...)`.

    Save again after these changes; loading an older config cannot recover tools it never stored. The script saves and reloads the configuration. Uncomment its final `loaded_workflow.print_response(...)` call to run the research workflow with real model and search requests.
  </Step>

  <Step title="Run the example">
    Save the code above as `save_parallel_steps.py`, then run:

    ```bash
    python save_parallel_steps.py
    ```
  </Step>
</Steps>

Full source: [cookbook/93\_components/workflows/save\_parallel\_steps.py](https://github.com/agno-agi/agno/blob/8f36eaf2d18e91afa7b327eec66a3cd3685dcb87/cookbook/93_components/workflows/save_parallel_steps.py)
