> ## Documentation index
> Fetch the complete documentation index at: https://haarness.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Execution budgets

Budgets are the limits that stop one command, script or batch of child agents from running
forever or taking over your machine. By default a shell command has two minutes, four child agents
run at once, and a child agent cannot start its own. Change them when a build needs longer, or
when you want fewer things running at once.

A budget is not a security boundary. It bounds a command that hangs or loops; it does not stop
code that is trying to do harm.

## Change a budget

Put the settings under `execution` in `haarness.json`: `~/.config/haarness/haarness.json` for all
projects, or `haarness.json` or `.haarness/haarness.json` in one project. A project value replaces
only the settings it names.

```json
{
  "execution": {
    "shell_timeout_ms": 600000,
    "subagent_concurrency": 2
  }
}
```

In `config.toml`, the same keys go under `[execution]`. Unknown keys are an error.

## Why did my command stop after two minutes?

A shell command the agent runs has two minutes by default. The agent can set a different limit
on a single command. To change the default, set `shell_timeout_ms`; `0` removes the limit.

When the limit is reached, the command and every process it started are stopped. Without a limit,
**Esc Esc** in the terminal UI, or stopping the turn in Desktop, still stops it.

## Where did the rest of the output go?

When a command prints more than 50 KiB or 2,000 lines, the full output is saved to a file. The
agent sees the end of it and the file's path, and can read the rest.

## How many child agents run at once?

Four at a time, at each level. By default a child agent cannot start children of its own.

| To | Set |
| --- | --- |
| Run fewer child agents at once | `subagent_concurrency` to a smaller number |
| Let child agents start their own children | `subagent_depth` to `2` |
| Stop the agent from starting child agents | `subagent_depth` to `0` |

Stopping a turn stops all of its child agents too.

## What runs at the same time?

Reads, file listings, searches and web fetches run together, up to `read_parallelism` at a time.
Child agents started together run side by side, up to `subagent_concurrency`. Edits, shell
commands, MCP tools and everything else run one at a time, in the order the agent asked for them.

## All settings

| Setting | Default | Means |
| --- | ---: | --- |
| `shell_timeout_ms` | 120000 | Shell command limit; `0` means none |
| `subagent_concurrency` | 4 | Child agents running at once, per level |
| `subagent_depth` | 1 | How many levels of child agents; `0` turns them off |
| `read_parallelism` | 8 | Reads and searches run together |
| `media_max_bytes` | 20971520 | Largest image, PDF, audio or video the agent reads (20 MiB) |
| `code_timeout_ms` | 60000 | Time limit for a script the agent writes; `0` means none |
| `code_max_calls` | 100 | Tool calls one such script may make; `0` means no limit |
| `code_max_source_bytes` | 262144 | Largest such script; `0` turns the check off |
| `plan_read_tools` | `[]` | Extension tools the plan agent may use |

`subagent_concurrency`, `read_parallelism` and `media_max_bytes` must be greater than zero.

The `code_*` settings apply to the `execute` tool, where the agent writes a short JavaScript
program that calls MCP and browser tools. It needs `bun` on your `PATH`.

`plan_read_tools` lists exact extension tool names, such as `ext__code_search__query`, that you
have checked only read. Wildcards are refused. The plan agent can then use them.

## Limit the number of tool rounds

A turn can call tools as many times as it needs. To cap it:

```json
{
  "tools": { "max_rounds": 64 }
}
```

When a turn reaches the cap, its tools are switched off and the model is asked to sum up. A custom
agent's own step limit takes precedence.

## Extension limits

Extensions have their own limits, in `extensions.json` next to your other configuration (or
`.haarness/extensions.json` in a project):

```json
{
  "enabled": true,
  "timeout_ms": 30000,
  "tool_timeout_ms": 120000,
  "payload_max_bytes": 2097152,
  "entries": []
}
```

| Setting | Default | Means |
| --- | ---: | --- |
| `timeout_ms` | 30000 | Default limit for every step; `0` means none |
| `init_timeout_ms` | `timeout_ms` | Loading the extension |
| `hook_timeout_ms` | `timeout_ms` | Each hook it runs |
| `tool_timeout_ms` | `timeout_ms` | Each tool call |
| `payload_max_bytes` | 2097152 | Largest message to or from it (2 MiB) |

When a call times out or you stop it, the extension is stopped and the call is not retried. Its
tools fail until you reload or restart Haarness. Return large results as files instead of in the
message.

## Hook limits

A command [hook](https://haarness.ai/docs/cli/hooks.md) has 60 seconds by default. Set `timeout` (in seconds,
1 to 600) on the hook to change it.

## Related

- [Permissions](https://haarness.ai/docs/security/permissions.md) — what the agent may do, rather than for how long
- [Reasoning and ultracode](https://haarness.ai/docs/tui/reasoning.md) — watching child agents
