Skip to main content
A ready-to-run example is available here!
Experimental Feature: Parallel tool execution is still experimental. By default, tool_concurrency_limit is set to 1 (sequential execution). Increasing this value may improve runtime performance, but use at your own risk. Concurrent execution can lead to race conditions or unexpected behavior for tools that share state.

Overview

When an LLM requests multiple tool calls in a single response, the SDK can execute them concurrently rather than sequentially. This is controlled by the tool_concurrency_limit parameter on the Agent class. Benefits:
  • Faster execution when tools are independent (e.g., reading multiple files)
  • Better utilization of I/O-bound operations
  • Enables parallel sub-agent delegation
When to use:
  • Running multiple read-only operations simultaneously
  • Delegating to multiple sub-agents at once
  • Executing independent API calls or file operations

Configuration

Setting the Concurrency Limit

Configure tool_concurrency_limit when creating an Agent:
import os
from openhands.sdk import Agent, LLM, Tool
from openhands.tools.terminal import TerminalTool
from openhands.tools.file_editor import FileEditorTool

llm = LLM(
    model="anthropic/claude-sonnet-4-5-20250929",
    api_key=os.getenv("LLM_API_KEY"),
)

agent = Agent(
    llm=llm,
    tools=[
        Tool(name=TerminalTool.name),
        Tool(name=FileEditorTool.name),
    ],
    # Execute up to 4 tools concurrently
    tool_concurrency_limit=4,
)

Concurrency Limit Values

ValueBehavior
1 (default)Sequential execution—tools run one at a time
2-8Moderate parallelism—good for most use cases
>8High parallelism—only for I/O-heavy workloads with independent tools. Risk of resource exhaustion.
The optimal value depends on your workload. Start with a lower value (e.g., 4) and increase if needed.

Use Cases

Parallel File Operations

When reading multiple independent files:
# Agent can read multiple files concurrently
agent = Agent(
    llm=llm,
    tools=[Tool(name=FileEditorTool.name)],
    tool_concurrency_limit=4,
)

# The agent might request:
# - file_editor view /path/to/file1.py
# - file_editor view /path/to/file2.py
# - file_editor view /path/to/file3.py
# All three execute concurrently

Parallel Sub-Agent Delegation

Combine with TaskToolSet for parallel task processing:
from openhands.tools.task import TaskToolSet

# Orchestrator with high concurrency for delegation
main_agent = Agent(
    llm=llm,
    tools=[
        Tool(name=TaskToolSet.name),
        Tool(name=TerminalTool.name),
        Tool(name=FileEditorTool.name),
    ],
    tool_concurrency_limit=8,  # Handle multiple delegations at once
)

Sub-Agents with Their Own Parallelism

Each sub-agent can have its own concurrency limit:
def create_analysis_agent(llm: LLM) -> Agent:
    """Sub-agent that runs multiple analysis tools in parallel."""
    return Agent(
        llm=llm,
        tools=[
            Tool(name=TerminalTool.name),
            Tool(name=FileEditorTool.name),
        ],
        tool_concurrency_limit=4,  # Sub-agent also runs tools in parallel
    )

Considerations

Thread Safety

Not all tools are safe to run concurrently. Be careful with:
  • Tools that modify shared state
  • Tools that write to the same files
  • Tools with external side effects that depend on execution order
  • Deadlocks when tools wait on resources held by other concurrent tools
  • Resource exhaustion (file handles, memory, network connections)

When NOT to Use

  • Tools that must execute in a specific order
  • Operations that modify the same files
  • Workflows where one tool’s output feeds into another