Canonical: https://botbento.com/blog/agent-loop-max-turns-cap/
Format: Markdown representation of the public HTML page.

[Home](/) / [Blog](/blog/)

FIELD NOTES / 5 MIN READ

# What Turn Limit Stops an Agent Loop Without Killing Real Work?

Both major agent SDKs let you cap how many tool-use rounds a loop can run before it stops on its own. The cap isn't a timeout and isn't a cost limit — it's a count of reasoning-and-tool-call rounds, and the two SDKs count a 'turn' slightly differently. Set the number too low and a real task gets cut off mid-work; set it too high and a stuck agent burns tokens for a long time before anyone notices. This piece works through what a turn actually counts, what happens the moment you hit the cap, and how to size the number for a specific task instead of guessing.

By BotBento Editorial · Published 2026-10-20 · Updated 2026-10-20

AI-assisted editorial: researched and drafted with AI using the primary sources linked below. Examples are illustrative; they are not measured product results. [Editorial policy](/editorial/).

## In this article

- [What Actually Counts as One Turn](#what-counts-as-a-turn)
- [A Worked Example: Same Debug Task, Two SDKs](#worked-example-two-sdks)
- [What Happens the Moment You Hit the Cap](#what-happens-when-you-hit-it)
- [A Turn Cap Is Not a Timeout or a Budget Cap](#turns-vs-timeout-vs-budget)
- [How to Pick a Starting Number](#picking-a-number)[Read as Markdown ](/text/blog/agent-loop-max-turns-cap/index.md)

## Key takeaways

- A 'turn' counts differently per SDK — Claude Agent SDK counts tool-use turns, OpenAI Agents SDK counts AI invocations including their tool calls — so check your framework's definition before setting a number.
- Hitting the cap isn't a crash. Claude returns a result message with subtype error\_max\_turns; OpenAI raises a MaxTurnsExceeded exception. Your code has to catch that case explicitly or the run just disappears.
- Size the cap to the worst reasonable version of the task (count the happy-path steps, multiply by a buffer), then watch how often runs actually hit it before raising the number further.

## What Actually Counts as One Turn

In the Claude Agent SDK, a turn cap counts tool-use turns only — the documentation gives an example where a four-step exchange (three tool-use steps plus one final text-only reply) would have been stopped by max\_turns=2 before the editing step, because the final text-only response doesn't consume the budget the same way.

The OpenAI Agents SDK counts turns differently: a turn is one AI invocation, and any tool calls that invocation produces are part of that same turn rather than separate ones. The Runner tracks this as current\_turn against the max\_turns ceiling you pass in, and the loop ends as soon as the model returns a final output, a handoff is requested, or the turn count runs out.

Those two definitions aren't interchangeable. A Claude session with max\_turns=10 and an OpenAI run with max\_turns=10 won't necessarily tolerate the same amount of actual tool work, because one is step-based and one is invocation-based. If you're porting a cap from one framework to the other, re-derive it from the task, don't copy the number.

Sources: [How the agent loop works - Claude Code Docs](https://code.claude.com/docs/en/agent-sdk/agent-loop), [Results - OpenAI Agents SDK](https://openai.github.io/openai-agents-python/ref/result/), [Running agents - OpenAI Agents SDK](https://openai.github.io/openai-agents-python/running_agents/).

## A Worked Example: Same Debug Task, Two SDKs

Say the task is: find and fix the bug causing test failures in an auth module. In the Claude Agent SDK, a realistic configuration sets allowed\_tools to Read, Edit, Bash, Glob and Grep, and sets max\_turns=30 with a comment calling it out plainly as a guard to 'prevent runaway sessions.' Thirty tool-use turns gives the agent room to search several files, run the test suite more than once, and make an edit, without leaving the cap so high that a confused agent can loop for an hour.

In the OpenAI Agents SDK, the same shape of task is run through Runner.run with an explicit max\_turns value and, optionally, an error\_handlers dict keyed by failure kind — the supported keys are 'max\_turns', 'model\_refusal', and 'invalid\_final\_output'. Passing an on\_max\_turns handler lets you return a synthesized fallback answer like 'I couldn't finish within the turn limit' instead of letting an unhandled exception kill the run outright.

Both SDKs let you disable the cap entirely — Claude Agent SDK treats max\_turns=0 the same as leaving it unset, and OpenAI Agents SDK lets you pass max\_turns=None to turn the limit off. Neither vendor recommends doing that for unattended work; the cap exists specifically to catch loops that would otherwise run unbounded.

Sources: [How the agent loop works - Claude Code Docs](https://code.claude.com/docs/en/agent-sdk/agent-loop), [Running agents - OpenAI Agents SDK](https://openai.github.io/openai-agents-python/running_agents/), [Configure your agent - Claude Code Docs](https://code.claude.com/docs/en/agent-sdk/configuration).

## What Happens the Moment You Hit the Cap

Claude Agent SDK: when a session hits maxTurns, it ends with a result message whose subtype is error\_max\_turns, and the agent-loop documentation notes plainly that no result field is available in that case — there's no partial answer to read off the result object directly. The Python reference adds a wrinkle: check terminal\_reason before subtype, because a run that failed on something like an API error can still report subtype 'success' with the real cause sitting in terminal\_reason.

Subagents behave a little differently. When a subagent — one invoked by the AgentDefinition's maxTurns field rather than the top-level session — hits its limit, Claude Code marks its output as partial rather than discarding it, and the calling agent can resume that subagent to continue from where it stopped. That resume behavior needs Claude Code v2.1.246 or later.

OpenAI Agents SDK: hitting max\_turns raises a MaxTurnsExceeded exception, a subclass of the SDK's base AgentsException, unless you've registered an error handler for the 'max\_turns' key. Without a handler, that exception propagates up and the caller has to catch it like any other unhandled error — there's no partial-output object waiting for you the way there sometimes is on the Claude side.

Sources: [How the agent loop works - Claude Code Docs](https://code.claude.com/docs/en/agent-sdk/agent-loop), [Agent SDK reference - Python - Claude Code Docs](https://code.claude.com/docs/en/agent-sdk/python), [Subagents in the SDK - Claude Code Docs](https://code.claude.com/docs/en/agent-sdk/subagents), [Exceptions - OpenAI Agents SDK](https://openai.github.io/openai-agents-python/ref/exceptions/), [Running agents - OpenAI Agents SDK](https://openai.github.io/openai-agents-python/running_agents/).

## A Turn Cap Is Not a Timeout or a Budget Cap

It's tempting to treat max\_turns as your only runaway-loop defense, but it only counts rounds, not wall-clock time or spend. A loop that makes ten turns in three seconds and a loop that makes ten turns over twenty minutes both hit the same max\_turns cap at the same count — if you need a time limit specifically, that's a separate per-call or per-session timeout, not something max\_turns gives you.

The Claude Agent SDK ships a second, independent cap for exactly this gap: maxBudgetUsd / max\_budget\_usd, which stops the session at an estimated dollar amount regardless of how many turns that took. Both caps are off by default, and when either one fires, the run ends with a result message whose subtype names which cap tripped — error\_max\_turns or error\_max\_budget\_usd. If your actual worry is cost rather than loop count, set the budget cap too; a generous turn limit with no budget cap still lets an agent that calls an expensive tool on every turn run up a large bill well before it runs out of turns.

Sources: [Configure your agent - Claude Code Docs](https://code.claude.com/docs/en/agent-sdk/configuration).

## How to Pick a Starting Number

Start from the happy path, not a round number. Write down the actual steps a successful run takes — for a PR review bot that reads a diff, greps for related tests, checks one more file, and writes a comment, that's roughly four turns in the Claude counting scheme. Multiply by two or three to leave room for a retry or an extra lookup, and you land on a cap like 10, which matches the kind of value you'll see used for review-style tasks in practice.

For tasks with a wider range of plausible step counts — an open-ended debugging task where the agent might need to inspect several files before finding the bug — size the cap toward the upper end of what's reasonable, use a value like 30, and lean on the partial-output-and-resume path for subagents, or an explicit max\_turns error handler for OpenAI Agents SDK runs, rather than trying to guess a tighter number up front.

Once the cap is in place, the number isn't permanent. Track how often live runs actually hit error\_max\_turns or raise MaxTurnsExceeded. A cap that's never hit is probably fine as-is or could be tightened to catch runaway loops faster. A cap that's hit often on otherwise-successful tasks is too tight — raise it. A cap that's hit often alongside genuinely stuck or repeating behavior means the problem isn't the number, it's the loop logic, and raising the cap will just make the stuck run more expensive.

## Primary sources

Sources checked 2026-10-20. Standards and product documentation can change; follow the linked version when implementing.

- [Configure your agent - Claude Code Docs](https://code.claude.com/docs/en/agent-sdk/configuration) — Anthropic
- [How the agent loop works - Claude Code Docs](https://code.claude.com/docs/en/agent-sdk/agent-loop) — Anthropic
- [Agent SDK reference - Python - Claude Code Docs](https://code.claude.com/docs/en/agent-sdk/python) — Anthropic
- [Subagents in the SDK - Claude Code Docs](https://code.claude.com/docs/en/agent-sdk/subagents) — Anthropic
- [Running agents - OpenAI Agents SDK](https://openai.github.io/openai-agents-python/running_agents/) — OpenAI
- [Exceptions - OpenAI Agents SDK](https://openai.github.io/openai-agents-python/ref/exceptions/) — OpenAI
- [Results - OpenAI Agents SDK](https://openai.github.io/openai-agents-python/ref/result/) — OpenAI

BotBento is in development. [Suggest a correction](/contact/).
