---
title: Microsoft Agent Framework Workflows - State Isolation
description: In-depth look at state isolation and thread safety in Microsoft Agent Framework Workflows.
zone_pivot_groups: programming-languages
author: TaoChenOSU
ms.topic: tutorial
ms.author: taochen
ms.date: 09/12/2025
ms.service: agent-framework
---

# Microsoft Agent Framework Workflows - State Isolation

In real-world applications, properly managing state is critical when handling multiple tasks or requests. Without proper isolation, shared state between different workflow executions can lead to unexpected behavior, data corruption, and race conditions. This article explains how to ensure state isolation within Microsoft Agent Framework Workflows, providing insights into best practices and common pitfalls.

## Mutable Workflow Builders vs Immutable Workflows

Workflows are created by workflow builders. Workflow builders are generally considered mutable, where one can add, modify start executor or other configurations after the builder is created or even after a workflow has been built. On the other hand, workflows are immutable in that once a workflow is built, it cannot be modified (no public API to modify a workflow).

This distinction is important because it affects how state is managed across different workflow executions. It is not recommended to reuse a single workflow instance for multiple tasks or requests, as this can lead to unintended state sharing. Instead, it is recommended to create a new workflow instance from the builder for each task or request to ensure proper state isolation and thread safety.

## Ensuring State Isolation in Workflow Builders

When an executor instance is passed directly to a workflow builder, that executor instance is shared among all workflow instances created from the builder. This can lead to issues if the executor instance contains state that should not be shared across multiple workflow executions. To ensure proper state isolation and thread safety, it is recommended to use factory functions that create a new executor instance for each workflow instance.

::: zone pivot="programming-language-csharp"

Coming soon...

::: zone-end

::: zone pivot="programming-language-python"

Non-thread-safe example:

```python
executor_a = CustomExecutorA()
executor_b = CustomExecutorB()

workflow_builder = WorkflowBuilder()
# executor_a and executor_b are passed directly to the workflow builder
workflow_builder.add_edge(executor_a, executor_b)
workflow_builder.set_start_executor(executor_b)

# All workflow instances created from the builder will share the same executor instances
workflow_a = workflow_builder.build()
workflow_b = workflow_builder.build()
```

Thread-safe example:

```python
workflow_builder = WorkflowBuilder()
# Register executor factory functions with the workflow builder
workflow_builder.register_executor(factory_func=CustomExecutorA, name="executor_a")
workflow_builder.register_executor(factory_func=CustomExecutorB, name="executor_b")
# Add edges using registered factory function names
workflow_builder.add_edge("executor_a", "executor_b")
workflow_builder.set_start_executor("executor_b")

# Each workflow instance created from the builder will have its own executor instances
workflow_a = workflow_builder.build()
workflow_b = workflow_builder.build()
```

::: zone-end

> [!TIP]
> To ensure proper state isolation and thread safety, also make sure that executor instances created by factory functions do not share mutable state.

## Agent State Management

Agent context is managed via agent threads. By default, each agent in a workflow will get its own thread unless the agent is managed by a custom executor. For more information, refer to [Working with Agents](./using-agents.md).

Agent threads are persisted across workflow runs. This means that if an agent is invoked in the first run of a workflow, content generated by the agent will be available in subsequent runs of the same workflow instance. While this can be useful for maintaining continuity within a single task, it can also lead to unintended state sharing if the same workflow instance is reused for different tasks or requests. To ensure each task has isolated agent state, use agent factory functions in your workflow builder to create a new workflow instance for each task or request.

::: zone pivot="programming-language-csharp"

Coming soon...

::: zone-end

::: zone pivot="programming-language-python"

Non-thread-safe example:

```python
writer_agent = AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
    instructions=(
        "You are an excellent content writer. You create new content and edit contents based on the feedback."
    ),
    name="writer_agent",
)
reviewer_agent = AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
    instructions=(
        "You are an excellent content reviewer."
        "Provide actionable feedback to the writer about the provided content."
        "Provide the feedback in the most concise manner possible."
    ),
    name="reviewer_agent",
)

builder = WorkflowBuilder()
# writer_agent and reviewer_agent are passed directly to the workflow builder
builder.add_edge(writer_agent, reviewer_agent)
builder.set_start_executor(writer_agent)

# All workflow instances created from the builder will share the same agent
# instances and agent threads
workflow = builder.build()
```

Thread-safe example:

```python
def create_writer_agent() -> ChatAgent:
    """Factory function to create a Writer agent."""
    return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
        instructions=(
            "You are an excellent content writer. You create new content and edit contents based on the feedback."
        ),
        name="writer_agent",
    )

def create_reviewer_agent() -> ChatAgent:
    """Factory function to create a Reviewer agent."""
    return AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
        instructions=(
            "You are an excellent content reviewer."
            "Provide actionable feedback to the writer about the provided content."
            "Provide the feedback in the most concise manner possible."
        ),
        name="reviewer_agent",
    )

builder = WorkflowBuilder()
# Register agent factory functions with the workflow builder
builder.register_agent(factory_func=create_writer_agent, name="writer_agent")
builder.register_agent(factory_func=create_reviewer_agent, name="reviewer_agent")
# Add edges using registered factory function names
builder.add_edge("writer_agent", "reviewer_agent")
builder.set_start_executor("writer_agent")

# Each workflow instance created from the builder will have its own agent
# instances and agent threads
workflow = builder.build()
```

::: zone-end

## Conclusion

State isolation in Microsoft Agent Framework Workflows can be effectively managed by using factory functions with workflow builders to create fresh executor and agent instances. By creating new workflow instances for each task or request, you can maintain proper state isolation and avoid unintended state sharing between different workflow executions.

## Next Steps

- [Learn how to visualize workflows](./visualization.md).
