---
title: "Limits and spend"
description: "Agent definition fields for limits and spend."
canonical_url: "https://docs.oz0.ai/reference/agent-definition/limits"
---
# Limits and spend

> Agent definition fields for limits and spend.

For: Plugin authors looking up agent fields.

Look up the fields below when editing an agent definition.

<field-group>
<field name="limits.max_steps" type="integer">

Model calls per job. Default 50. A harness agent's session gets it as its turn limit only when it is set; a [remote agent](https://docs.oz0.ai/build/apps/remote-agents#the-agent-definition)'s counts the provider's model requests.

</field>

<field name="limits.max_tokens" type="integer">

Input plus output tokens per job.

</field>

<field name="limits.timeout" type="duration">

How long a job may run, such as `90s`, `10m` or `1h30m`.

</field>

<field name="limits.max_cost_usd" type="number">

The default budget of the agent's jobs, in US dollars, for a job and every job it delegates to. `run --budget` overrides it for one job. Unset means no budget.

</field>

<field name="limits.max_output_tokens" type="integer">

The most each of the agent's model requests may answer, such as `4k`: the runtime sends it as the request's `max_tokens`, and the gateway [reserves](https://docs.oz0.ai/build/parts/contracts-and-limits/budgets#each-call-reserves-its-worst-case) it against the job's budgets before each call. Unset leaves the model's own default, often its largest output, which a budget then holds in full while each call runs. Pydantic AI agents.

</field>

<field name="limits.tool_tokens" type="integer">

The most the agent's tool definitions may come to in every model request, as an estimate of tokens: every function it lists, or with `tool_loading: lazy` the two discovery tools, and its built-ins. Unset is 8,000. `plugin lint`, `plugin test`, `plugin pack` and the studio fail past it ([the size budget](https://docs.oz0.ai/build/parts/tools/definitions#the-size-budget)). A whole number from 1 to 1,000,000.

</field>

<field name="limits.startup_tokens" type="integer">

The most the platform adds to the agent's start-up context after its instructions, as an estimate of tokens: the index of its [skills](https://docs.oz0.ai/build/parts/skills), then the [start-up text](https://docs.oz0.ai/build/parts/records-and-startup#start-up-text) of plugins it uses, such as the memory plugin's accepted decisions and definitions, which gets what the index leaves. Its own instructions do not count. Unset is 4,000. `plugin lint`, `plugin test`, `plugin pack` and the studio fail past it (`startup.budget`). A whole number from 1 to 1,000,000.

</field>

<field name="limits.memory_mb" type="integer">

The most memory each sandbox of the agent's sessions may use on a Linux node, swap included, in MiB: the session, and each command it runs in a sandbox of its own (an ACP terminal). Unset is 4096 for a session and 2048 for a command; the tenant's ceiling (`oz0 tenant sandbox-limits`) is the most it gets. A session that runs out is stopped.

</field>

<field name="limits.pids" type="integer">

The most processes and threads each of those sandboxes may run; unset is 1024 for a session and 512 for a command. A fork past it fails.

</field>

<field name="limits.cpus" type="number">

The most CPU time each of those sandboxes gets, in cores (`1.5` is one and a half); unset is 2.

</field>

<field name="limits.concurrent" type="integer">

The most jobs of the agent that run at once in the tenant, child jobs included, counted for the whole tenant and never per person: a job past it waits at its start until one of them ends, asking again about every 5 seconds, and is never refused for it. It starts at its first ask after a job of the agent completes, fails or is cancelled; a job stopped by a person or timed out frees its place within about 30 seconds.

A job that runs under one of the agent's own jobs (its best-of candidates, a quarantine reader, a delegation back to the agent further down) runs in that job's place and takes none of its own, since the job above it waits for it.

If the edge cannot count the agent's jobs, a start asks again and goes ahead after five such asks in a row rather than wait for good; an answer that the agent is still at its limit starts that count again, so a start that has waited a long while still waits through one busy answer.

A gate's shadow runs do not count. It keeps one busy agent from taking every slot of a [shared pool](https://docs.oz0.ai/concepts/routing#shared-pools), and works without Temporal's fair dispatch.

A whole number from 1 to 1,000; unset is no limit of its own. A flow has none: its steps carry their agents'.

</field>

<field name="limits.tree" type="map">

Limits of the whole job tree this agent's job is the root of: `model_calls`, `tokens`, `children` (child jobs in all), `fan_out` (child jobs running at once), `depth` and `wait` (the time each of its jobs may wait for people in all, a duration such as `8h`). Zero or unset takes the tenant's (`oz0 tenant spend`), then the defaults: no limit on calls, tokens and waiting, 500 children, 100 at once, 10 deep. `-1` (`none` for `wait`) is no limit. See [Limits of a whole job tree](https://docs.oz0.ai/build/parts/contracts-and-limits/limits#limits-of-a-whole-job-tree).

</field>

<field name="on_loop" type="string">

What a loop does ([Loops](https://docs.oz0.ai/build/parts/contracts-and-limits/limits#loops)): `wait` (the default) makes the job wait for a person as an approval of kind `loop`; `stop` ends it with `LoopDetected`; `report` only reports. Unset, a loop among a harness session's own tools (its shell, reads, edits) is reported, since only repeats in a row count there.

</field>

<field name="loops" type="map">

The loop detectors' thresholds: `repeats` (the same call, 3), `cycles` (a sequence of two to four calls repeated in a row, 2) and `no_progress` (results in a row that add nothing, after which only the answer is left, 5).

</field>

<field name="on_budget" type="string">

What a spent job tree's budget does ([Budgets that wait](https://docs.oz0.ai/build/parts/contracts-and-limits/budgets#budgets-that-wait)): `wait` for a person to raise it, or `fail` with `BudgetExceeded`. Unset takes the tenant's; when neither says, a tree a person started waits and any other fails.

</field>

<field name="on_unknown" type="string">

What a write whose outcome is unknown does ([Unknown outcomes](https://docs.oz0.ai/agents/approvals/recovery#unknown-outcomes)): a call of a function that is not [retry-safe](https://docs.oz0.ai/build/parts/tools/definitions#retry-safe-functions) ran out of time, lost its node, or ended with an error the platform cannot read after its request went out.

`wait` asks a person, who answers that it happened, that it runs again under the same idempotency key, or that the job stops; `fail` fails the job with the failure kind `unknown_outcome`.

The plugin's configuration for the agent overrides this value; when neither says, the tenant's default applies (`oz0 tenant spend --on-unknown`), and when that is unset too, a job a person started (an account or an operator) waits and any other (a routine's, an event's, an API key's) fails. A flow step's agent keeps its own.

</field>

<field name="reserve" type="string">

What a model call whose worst case does not fit the tree's budget does ([Each call reserves its worst case](https://docs.oz0.ai/build/parts/contracts-and-limits/budgets#each-call-reserves-its-worst-case)): `last_call` (the default) lets it start when nothing else of the budget runs and the budget is not spent, so the tree passes its budget by at most one call's reservation; `strict` refuses it, so the tree never passes its budget. Unset takes the tenant's (`oz0 tenant spend --reserve`); `last_call` does not loosen a tenant's `strict`.

</field>

<field name="spend" type="map">

When the agent is told it is running low and asked to finish: `warn_share` (0.8), `soft_wall` (0.85: only the answer is left), and `forecast` (`chance` 0.8, `min_runs` 20, `off`), which asks a person before the wall from the agent's own finished runs.

</field>
</field-group>

[Back to the agent definition](https://docs.oz0.ai/reference/agent-definition).


## Sitemap

See the full [sitemap](https://docs.oz0.ai/sitemap.md) for all pages.
