An agent can decide to read three documents, update a file, and check the result in a single model step. Whether those operations overlap is a runtime decision with consequences for latency, shared state, and downstream capacity.
That decision became easier to express this week. AI SDK’s [email protected] release, published on October 14, 2026, adds configurable tool execution concurrency. The implementation merged on October 13; the official pull request records the subsequent package publication. It gives applications a scheduling control worth reviewing before simply turning parallelism up.
The useful question is specific: which operations can overlap without changing the answer or overwhelming the systems they call?
Separate the plan from its execution
AI SDK now accepts toolCallConcurrency in generateText, streamText, and ToolLoopAgent. A positive integer caps simultaneous SDK-executed calls within a step. With 1, calls execute sequentially in the model’s emitted order. Omitting the option preserves concurrent execution. These are the documented API semantics.
The distinction between generation and execution matters. A model can propose several calls while the application runs only one at a time. Conversely, restricting what the model generates is a separate control. The tool-calling guide distinguishes this setting from provider options such as parallelToolCalls, and excludes provider-executed and client-side tools from its local scheduler.
Illustrative configuration, assuming an application has already supplied its model and tools:
const result = await generateText({
model,
tools,
prompt: "Update the document, then inspect it.",
toolCallConcurrency: 1,
})
This asks the runtime to preserve execution order. The application still needs to decide whether the proposed operations are valid.
Begin with dependencies
Consider an illustrative document assistant with three operations: read a source document, update a draft, and read the draft back.
If the last read must observe the update, those operations have a dependency. Starting them together can produce a perfectly successful read of the wrong version. Making everything sequential is a reasonable initial policy for this small workflow.
Now consider three independent searches over separate reference documents. If none changes state or depends on another’s result, overlapping them may reduce waiting. Serial execution would spend time protecting an ordering the product does not require.
Even independent reads deserve scrutiny. Three queries against one busy database share capacity. A tool labelled “read” might also refresh a cache or record access. Classify calls by their actual behavior and the resources they share.
For a mixed workflow, I would separate retrieval from mutation. Gather independent evidence together, then perform the dependent update and verification through an explicit sequence. If the second action needs an identifier returned by the first, request it in a later step after that result exists. Sequential execution cannot retrofit a missing result into arguments already generated.
AI SDK’s loop controls allow applications to change the active tools between steps. That offers a practical way to expose only the operations appropriate to each phase.
A local cap leaves shared capacity to you
A limit of four sounds restrained until many users run agents at the same time.
In an illustrative workload, 25 active steps, each allowed four calls, could produce 100 simultaneous local tool executions. If each tool starts additional requests internally, pressure on a downstream service can be higher still.
The API reference defines the setting within a step. My architectural conclusion is that a shared service also needs a shared capacity policy.
I would place that policy near the resource it protects: a queue for an expensive integration, a bounded pool for database work, or an admission limit shared across application replicas. Keep tenant fairness visible so one large run cannot monopolize the available capacity.
Concurrency and request rate also answer different questions. A few fast calls can still create a large burst over a short interval. Choose limits using the downstream service’s actual contract and observed behavior, rather than assuming a small concurrency number satisfies every quota.
Sequential execution does not validate the plan
Preserving model order only helps when that order is appropriate.
Suppose the model emits “delete the draft” before “read the draft.” Sequential execution makes that sequence orderly; it does not make it useful. Likewise, an update followed by a verification read can still be interrupted by another agent changing the same document.
For shared mutable resources, I would retain version checks or other application-level coordination. For operations that may be retried, define how repeated requests are recognized. These are separate design decisions from choosing how many calls start together.
A tool’s return value also deserves a precise contract. If it returns “accepted” after starting background work, a later tool should not interpret that as “the update is visible.” Return enough information to check completion, or make the dependent operation wait on an explicit completion condition.
Measure waiting before choosing a number
I would compare sequential, modestly bounded, and current-default execution against the same representative tasks.
Measure the whole run, then distinguish time waiting for a slot from time spent inside a tool. Otherwise, a slow integration and an overloaded scheduler can look identical to the user.
AI SDK exposes tool execution lifecycle callbacks around tool execution. Use those alongside application timestamps to inspect duration, failures, and the path from proposal to completion.
Include a slow tool, a failed tool, concurrent users, and calls that touch the same resource. Check final state as well as completion time. A faster answer based on stale data is a regression.
Streaming requires one additional consideration: the documented scheduler keeps a streaming tool’s slot until its final output or error. Early progress output therefore does not mean capacity has been released.
Choose a policy you can explain
Start by writing down which calls depend on earlier results, which share mutable state, and which consume scarce capacity. Use sequential execution for ordering requirements, bounded parallelism for independent work, and resource-level controls for limits shared across runs.
Then test that policy under the workload users actually create.
The useful outcome of this week’s SDK change is a more explicit scheduling decision. A good concurrency setting should have an explanation grounded in dependencies and capacity, plus measurements showing that the tradeoff improves the product.