Tool Executors
Tool executors control whether tools from a single assistant turn run concurrently or sequentially. Both SDKs default to concurrent execution.
Concurrent Executor
Section titled “Concurrent Executor”Concurrent execution runs all tool calls from a single turn in parallel. This is the default in both SDKs — you get it without any extra configuration.
from strands import Agentfrom strands.tools.executors import ConcurrentToolExecutor
agent = Agent( tool_executor=ConcurrentToolExecutor(), tools=[weather_tool, time_tool])# or simply Agent(tools=[weather_tool, time_tool])
agent("What is the weather and time in New York?")import { Agent } from '@strands-agents/sdk'
const agent = new Agent({ tools: [weatherTool, timeTool], toolExecutor: 'concurrent',})// or simply: new Agent({ tools: [weatherTool, timeTool] })
await agent.invoke('What is the weather and time in New York?')Assuming the model returns weather_tool and time_tool use requests, the concurrent executor runs both at the same time. End-to-end latency scales with the slowest tool rather than their sum.
Sequential Behavior
Section titled “Sequential Behavior”On certain prompts, the model may decide to return one tool use request at a time. Under these circumstances, the tools will execute sequentially. Concurrency is only achieved if the model returns multiple tool use requests in a single response. Certain models however offer additional abilities to coerce a desired behavior. For example, Anthropic exposes an explicit parallel tool use setting (docs).
Sequential Executor
Section titled “Sequential Executor”Use sequential execution when tool order matters — for example, when a later tool depends on a side effect of an earlier one:
from strands import Agentfrom strands.tools.executors import SequentialToolExecutor
agent = Agent( tool_executor=SequentialToolExecutor(), tools=[screenshot_tool, email_tool])
agent("Please take a screenshot and then email the screenshot to my friend")import { Agent } from '@strands-agents/sdk'
const agent = new Agent({ tools: [screenshotTool, emailTool], toolExecutor: 'sequential',})
await agent.invoke('Take a screenshot and email it to my friend')Assuming the model returns screenshot_tool and email_tool use requests, the sequential executor runs both in the order given.
Event Ordering
Section titled “Event Ordering”Both modes preserve per-tool event order. In concurrent mode, events from different tools may interleave across that per-tool sequence.
Per-tool event order: BeforeToolCallEvent → ToolStreamEvent* → AfterToolCallEvent → ToolResultEvent.
Per-tool event order: BeforeToolCallEvent → ToolStreamUpdateEvent* → AfterToolCallEvent → ToolResultEvent.
Cancellation
Section titled “Cancellation”Cancellation works identically in both modes. Call agent.cancel() to request cooperative cancellation. In TypeScript, this flips agent.cancelSignal.
- Pre-launch cancel: set
BeforeToolCallEvent.cancel_toolon a per-tool hook to produce an error result for that tool. - Mid-flight cancel in sequential mode short-circuits not-yet-started tools. In concurrent mode, all tools have already launched, so each in-flight tool must cooperatively check for cancellation to stop early.
- Pre-launch cancel: set
BeforeToolsEvent.cancelon the batch-level hook, or callagent.cancel()before tools start, to produce error results for every tool in the batch. - Mid-flight cancel in sequential mode short-circuits not-yet-started tools. In concurrent mode, all tools have already launched, so each in-flight tool must cooperatively observe
agent.cancelSignalto stop early.
Custom Executors
Section titled “Custom Executors”Custom tool executors are not currently supported but are planned for a future release. You can track progress on this feature at GitHub Issue #762.