---
title: The round-robin pattern | Letta Docs
description: Distribute tasks evenly across multiple agents using a rotating sequence to ensure fair workload distribution.
---

Distribute incoming tasks evenly across multiple agents in a fixed rotation sequence. Each agent processes tasks in turn, ensuring fair workload distribution and preventing any single agent from being overwhelmed.

## When to use this pattern

The round-robin pattern works well when you need to:

- Distribute high-volume tasks evenly across multiple agents
- Prevent workload concentration on any single agent
- Ensure fair processing where each agent gets equal opportunities
- Maintain diverse perspectives by rotating agents through different tasks

### Example use case

A social media platform receives flagged content for moderation review. Three moderator agents review flagged posts in rotation:

- **Agent A** reviews posts 1, 4, 7, 10…
- **Agent B** reviews posts 2, 5, 8, 11…
- **Agent C** reviews posts 3, 6, 9, 12…

Each agent maintains memory of previous decisions, learning moderation patterns and policy edge cases over time.

## How it works

The pattern uses three key components:

1. A **pool of agents** with similar capabilities that process tasks independently
2. A **rotation index** maintained by the client to track which agent receives the next task
3. **Client orchestration** that distributes tasks sequentially to agents in the rotation order

## Implementation

### Step 1: Create the pool of agents

Create multiple agents with similar capabilities:

```
from letta_client import Letta
import os


client = Letta(api_key=os.getenv("LETTA_API_KEY"))


# Create three moderator agents
moderator_a = client.agents.create(
    name="moderator_a",
    model="anthropic/claude-sonnet-4-5-20250929",
    memory_blocks=[{
        "label": "persona",
        "value": "I review flagged social media posts for policy violations. I evaluate content against community guidelines and make moderation decisions."
    }]
)


moderator_b = client.agents.create(
    name="moderator_b",
    model="anthropic/claude-sonnet-4-5-20250929",
    memory_blocks=[{
        "label": "persona",
        "value": "I review flagged social media posts for policy violations. I evaluate content against community guidelines and make moderation decisions."
    }]
)


moderator_c = client.agents.create(
    name="moderator_c",
    model="anthropic/claude-sonnet-4-5-20250929",
    memory_blocks=[{
        "label": "persona",
        "value": "I review flagged social media posts for policy violations. I evaluate content against community guidelines and make moderation decisions."
    }]
)
```

Each agent has the same capabilities but maintains independent memory of their own moderation history.

### Step 2: Set up the rotation sequence

Create a list of agents and initialize the rotation index:

```
# Define rotation order
moderators = [moderator_a, moderator_b, moderator_c]


# Track current position in rotation
current_index = 0
```

### Step 3: Distribute tasks in rotation

For each incoming task, send it to the current agent and advance the rotation:

```
# Example: flagged posts arriving for review
flagged_posts = [
    "Post 1: User shared potentially misleading health information",
    "Post 2: Comment contains targeted harassment",
    "Post 3: Image may violate copyright",
    "Post 4: Spam advertisement posted multiple times",
    "Post 5: Hate speech reported by users"
]


# Distribute posts to moderators in round-robin fashion
for post in flagged_posts:
    current_moderator = moderators[current_index]


    response = client.agents.messages.create(
        agent_id=current_moderator.id,
        messages=[{"role": "user", "content": f"Review this flagged post: {post}"}]
    )


    print(f"{current_moderator.name} reviewed: {post}")
    print(f"Decision: {response.messages[-1].content}\n")


    # Advance to next moderator (with wraparound)
    current_index = (current_index + 1) % len(moderators)
```

The modulo operation `% len(moderators)` ensures the index wraps back to `0` after reaching the last agent.

### Step 4: Handle agent responses

Each agent processes tasks independently and maintains its own memory:

```
# Check what each moderator remembers
for moderator in moderators:
    messages = client.agents.messages.list(agent_id=moderator.id)
    print(f"{moderator.name} has reviewed {len(messages)} posts")
```

### Minimal example

```
from letta_client import Letta
import os


client = Letta(api_key=os.getenv("LETTA_API_KEY"))


# Create three agents
agents = []
for i in range(3):
    agent = client.agents.create(
        name=f"agent_{i}",
        model="anthropic/claude-sonnet-4-5-20250929",
        memory_blocks=[{
            "label": "persona",
            "value": f"I am agent {i}. I process tasks assigned to me."
        }]
    )
    agents.append(agent)


# Distribute tasks in round-robin
tasks = ["Task 1", "Task 2", "Task 3", "Task 4", "Task 5", "Task 6"]
current_index = 0


for task in tasks:
    current_agent = agents[current_index]
    client.agents.messages.create(
        agent_id=current_agent.id,
        messages=[{"role": "user", "content": task}]
    )
    print(f"{current_agent.name} received {task}")
    current_index = (current_index + 1) % len(agents)
```

**Output:**

```
agent_0 received Task 1
agent_1 received Task 2
agent_2 received Task 3
agent_0 received Task 4
agent_1 received Task 5
agent_2 received Task 6
```

## Best practices

- **Define clear agent capabilities**: Each agent in the pool should have similar capabilities. The round-robin pattern assumes agents are interchangeable. For specialized routing, use the [supervisor-worker pattern](/tutorials/multi-agent/supervisor-worker/index.md) instead.
- **Track rotation state**: Maintain the rotation index as part of your application state. If your application restarts, persist the index to resume the rotation.
- **Monitor agent workload**: Verify that the client distributes tasks evenly across agents. Large differences in task counts may indicate an issue with rotation logic.
- **Consider agent capacity**: The round-robin pattern assumes all agents have equal processing capacity. If agents process tasks at different speeds, consider weighted distribution or dynamic load balancing.
- **Use consistent agent ordering**: Maintain a consistent rotation order across application restarts for predictable task distribution.
