# Runtime limits (/docs/run/limits)



```ts
import { createAdmin } from "@nylorun/admin";

const admin = createAdmin();

const { limits } = await admin.settings.limits.get();
console.log(limits.httpToolTimeoutMs); // 300000

await admin.settings.limits.put({
  limits: { httpToolTimeoutMs: 600_000, sessionQueuedMessages: 20 },
});
```

From a terminal:

```sh
npx nylorun tenant settings limits get
npx nylorun tenant settings limits put limits.json
```

How large, how many, and how long what crosses the Runtime may be is the
Tenant's Runtime limits. They are a Tenant setting, set with a management key
the same way on a local or a remote Tenant: `admin.settings.limits`,
`nylorun tenant settings limits`, or `GET` / `PUT /v1/tenant/limits`. In
[Studio](/docs/run/studio#the-tenant), the Tenant page's **Limits** tab lists
them by area beside their defaults and edits one at a time.

## Set limits [#set-limits]

**A `put` replaces them all.** A limit left out takes its default. `get`
returns every limit in force (`{ limits }`), with the default filled in for each
the Tenant has not set, so putting back what `get` printed fixes today's
defaults as the Tenant's own values. Keep the limits you change in one place,
such as a `limits.json` in your repository holding only those, and put the
whole set each time.

* A limit above its ceiling, or under its floor, is `400`, naming the bound and
  why, and nothing changes.
* Each limit is read where it is checked, so a new value holds for the next
  request, write, call, or turn.
* An agent manifest's setup commands and input files are checked when it is
  saved, an Agent's labels whenever they are set, and a secret's value and
  hosts when it is written.
* An Agent made before a limit was lowered keeps running, within the lower
  limit where one applies at run time, such as a setup command's timeout or a
  disk version.

A name ending in `Bytes` counts bytes, `Ms` milliseconds, and `Chars`
characters. Every value is a whole number, at least 1, except
`modelProviderRetries`, `triggerJitterPercent`, and `triggerJitterMaxMs`, which
may be 0.

## What crossing one looks like [#what-crossing-one-looks-like]

| Limit                                | Past it                                                                                                                                                                                       |
| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `requestBodyBytes`                   | `413 limit_exceeded`.                                                                                                                                                                         |
| `recordEntryBytes`                   | A write into the session's record is `413 limit_exceeded` (`details.limit: "recordEntryBytes"`) to an API client, and `limit_exceeded` to a harness. A turn whose harness reports more fails. |
| `pageItems`, `exportPageItems`       | A page asked for with a larger `limit` holds this many, with a cursor to the rest.                                                                                                            |
| `toolAnswerBytes`                    | The tool call fails to the model with `mcp.too-large` or `http.too-large`.                                                                                                                    |
| `toolAttempts`                       | The tool call fails to the model with `tool.interrupted`.                                                                                                                                     |
| `sessionQueuedMessages`              | One more message is `429 queue_full`.                                                                                                                                                         |
| `triggerRunsPerHour`                 | Later runs that hour are skipped, `rate_limited`.                                                                                                                                             |
| `webhookBodyBytes`                   | The delivery is `413`, before it is verified.                                                                                                                                                 |
| `flowMapItems`, `flowLoopIterations` | The flow's turn fails with `map.too-many-items` or `loop.too-many-iterations`.                                                                                                                |
| `folderFiles`, `folderBytes`         | The save of an agent manifest is `413 limit_exceeded`, naming the limit in `details.limit`.                                                                                                   |
| `folderTextFileBytes`                | The save of an agent manifest is `422 folder_invalid`.                                                                                                                                        |

Elsewhere, the error message names the limit, its value, and where it is set
(`PUT /v1/tenant/limits`).

## Limits a harness gets [#limits-a-harness-gets]

A harness learns these in `turn.start.limits` and must respect them. A
[custom harness](/docs/build/harness) reads them there rather than assuming the
defaults.

| Limit               | What it holds                                                                                                                 | Default | Ceiling                                                        |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------- | -------------------------------------------------------------- |
| `recordEntryBytes`  | One event's payload, or one effect outcome, in a session's record. A transcript edit fills events up to it.                   | 960 KiB | 960 KiB: a 1 MiB record entry, less the event's envelope       |
| `modelCallBytes`    | A model call's body at the Model Gate.                                                                                        | 32 MiB  | About 512 MiB: one string                                      |
| `modelFileBytes`    | One file the Model Gate sends a model.                                                                                        | 8 MiB   | About 384 MiB: its base64 in one string                        |
| `toolAnswerBytes`   | An MCP or HTTP tool's answer the Tool Gate keeps, and the tool call bodies it reads.                                          | 8 MiB   | 32 MiB: half a Harness API frame                               |
| `harnessStateBytes` | A custom harness's state per session, as JSON.                                                                                | 256 KiB | 32 MiB: half a Harness API frame                               |
| `chunkBytes`        | One chunked Harness API answer or upload chunk, such as a range of a skill file or an artifact, and one range of a disk copy. | 16 MiB  | 48 MiB less 64 KiB: its base64 in one Harness API frame        |
| `folderEntries`     | The files of one folder version a harness writes, such as Nylorun's harness's outputs folder.                                 | 10,000  | About 4.6 million: entries of a folder's listing in one string |

## Limits only the Runtime checks [#limits-only-the-runtime-checks]

The names that start with `environment` are kept from before Agents. They
apply to an agent manifest's runtime section and to an Agent.

### Requests [#requests]

| Limit                   | What it holds                                                                                                         | Default | Ceiling                                 |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------- | ------- | --------------------------------------- |
| `requestBodyBytes`      | A Runtime or Management API request's JSON body.                                                                      | 1 MiB   | About 512 MiB: one string               |
| `messageParts`          | Parts, text and files, of one user message.                                                                           | 32      | One request body                        |
| `pageItems`             | Items one page of a listing holds. A page with no `limit` holds the route's default (50), or this when lower.         | 200     | About 179 million: one response body    |
| `exportPageItems`       | Calls one page of the model call export holds (`admin.models.exportCalls()`, `nylorun tenant calls`).                 | 1,000   | One response body                       |
| `environmentEventItems` | Events one read of an Agent's events returns. `from` reads on.                                                        | 1,000   | One response body                       |
| `inlineFileBytes`       | One file a message carries inline (AG-UI, A2A). Such an endpoint reads one file's base64 and `requestBodyBytes` more. | 20 MiB  | About 384 MiB: its base64 in one string |
| `a2aWaitMs`             | How long a blocking A2A `SendMessage` waits before it answers `WORKING`.                                              | 5 min   | A timer                                 |
| `errorExcerptChars`     | How much of a failed MCP server's or HTTP tool's answer an error quotes.                                              | 2,000   | One record entry, escaped               |
| `traceContentBytes`     | One content attribute of an exported span.                                                                            | 8 KiB   | 960 KiB: one record entry               |

### Labels [#labels]

| Limit               | What it holds                                        | Default | Ceiling          |
| ------------------- | ---------------------------------------------------- | ------- | ---------------- |
| `environmentLabels` | Labels on one Agent, checked whenever they are set.  | 32      | One request body |
| `artifactLabels`    | Labels on one artifact, checked when it is uploaded. | 32      | One request body |
| `labelKeyChars`     | The longest label key, an Agent's or an artifact's.  | 63      | One request body |
| `labelValueChars`   | The longest label value.                             | 256     | One request body |

### An agent manifest's runtime section [#an-agent-manifests-runtime-section]

Checked when the manifest is saved.

| Limit                      | What it holds                                                                         | Default | Ceiling                                                            |
| -------------------------- | ------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------ |
| `environmentSetupCommands` | Setup commands in one runtime section.                                                | 16      | One request body                                                   |
| `environmentFiles`         | Input file entries in one runtime section.                                            | 16      | One request body                                                   |
| `environmentFilesPerEntry` | Files one input file entry by hash names.                                             | 1,000   | One request body                                                   |
| `environmentSecretSlots`   | Secret slots one runtime section declares.                                            | 64      | One request body                                                   |
| `manifestDescriptionChars` | An agent manifest's `description`.                                                    | 1,024   | One request body                                                   |
| `secretDescriptionChars`   | A secret slot's `description`.                                                        | 500     | One request body                                                   |
| `setupCommandChars`        | One setup command.                                                                    | 4,096   | 43,690: one argument of `/bin/sh -c`, at 3 UTF-8 bytes a character |
| `setupCommandMs`           | The longest `timeout` a setup command may ask for. A command's default is 10 minutes. | 30 min  | A timer                                                            |
| `setupOutputChars`         | The end of a failed setup command's output its event keeps.                           | 4,096   | One record entry, escaped                                          |
| `setupReasonChars`         | The end of that output a failed pod's reason quotes.                                  | 500     | One record entry, escaped                                          |
| `setupCommandExcerptChars` | The start of the command the reason quotes.                                           | 80      | One record entry, escaped                                          |

### Secrets [#secrets]

Checked when a secret is written, and a manifest's slots when it is saved.

| Limit              | What it holds                                                   | Default | Ceiling          |
| ------------------ | --------------------------------------------------------------- | ------- | ---------------- |
| `secretValueChars` | The value of an `environment_secret` or `environment_variable`. | 8,192   | One request body |
| `secretHosts`      | Hosts one `environment_secret` may be sent to (`allowedHosts`). | 32      | One request body |

### Disk versions [#disk-versions]

| Limit                | What it holds                                                                         | Default | Ceiling                                                    |
| -------------------- | ------------------------------------------------------------------------------------- | ------- | ---------------------------------------------------------- |
| `diskVersionEntries` | Entries (files, links, empty directories) in one version of an Agent's disk.          | 200,000 | About 1.9 million: one disk listing in a Harness API frame |
| `diskVersionBytes`   | Bytes of files in one disk version.                                                   | 10 GiB  | A number                                                   |
| `diskLeaseMs`        | How long a disk copy's lease lasts unrenewed. The copy renews it every quarter of it. | 2 min   | A timer                                                    |
| `diskPodWaitMs`      | How long a disk copy waits for a pod's engine to connect.                             | 60 s    | A number                                                   |

### Model calls [#model-calls]

See [Timeouts and retries](/docs/run/models#timeouts-and-retries).

| Limit                  | What it holds                                                                                         | Default | Ceiling  |
| ---------------------- | ----------------------------------------------------------------------------------------------------- | ------- | -------- |
| `modelRequestMs`       | The longest one provider request may take.                                                            | 600 s   | A timer  |
| `modelIdleMs`          | How long a provider's stream may go without an event before the attempt is abandoned and tried again. | 300 s   | A timer  |
| `modelAttempts`        | Attempts per model call, the first included.                                                          | 3       | A number |
| `modelRetryDelayMs`    | The delay before the second attempt. It doubles each time, with jitter.                               | 2 s     | A timer  |
| `modelProviderRetries` | Retries the provider's SDK makes within one attempt.                                                  | 2       | A number |
| `modelRetryDelayMaxMs` | The longest delay the provider's SDK waits before one.                                                | 60 s    | A timer  |

### Tools [#tools]

| Limit                | What it holds                                                                                                                              | Default | Ceiling                                  |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ------- | ---------------------------------------- |
| `toolAttempts`       | Sends of an MCP or HTTP tool call, across crashes and lost hops, before it fails as `tool.interrupted`.                                    | 3       | A number                                 |
| `httpToolTimeoutMs`  | The longest `timeoutMs` an HTTP tool may ask for, checked when the manifest is saved and at each call. A tool's default is 60 s.           | 300 s   | A timer                                  |
| `mcpSnapshotBytes`   | What a session pins of its MCP servers' tools and instructions, which every turn carries. A server past it is left out, with a diagnostic. | 4 MiB   | 16 MiB: a quarter of a Harness API frame |
| `mcpPreviewMs`       | How long an [MCP server preview](/docs/run/credentials#preview-an-mcp-server) may take.                                                    | 15 s    | A timer                                  |
| `mcpMetadataBytes`   | The protected-resource metadata document a preview reads.                                                                                  | 64 KiB  | About 512 MiB: one string                |
| `toolRules`          | Rules in the Tenant's [tool policy](/docs/run/tool-policy).                                                                                | 200     | One request body                         |
| `toolRuleFieldChars` | A rule's `tool`, `server`, or `agent` selector, and a `when` path.                                                                         | 200     | One request body                         |
| `toolRuleTextChars`  | A rule's `reason`, and a `matches` expression.                                                                                             | 500     | One request body                         |
| `modelBudgets`       | [Model budgets](/docs/run/models#usage-and-budgets) the Tenant sets.                                                                       | 100     | One request body                         |

### Sessions [#sessions]

| Limit                   | What it holds                                                                                                     | Default | Ceiling  |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------- | ------- | -------- |
| `sessionQueuedMessages` | Messages one session's [queue](/docs/run/sessions#messages-while-a-turn-runs) holds while its turn runs or waits. | 100     | A number |

### Triggers and wakes [#triggers-and-wakes]

See [Triggers and wakes](/docs/run/triggers).

| Limit                   | What it holds                                                                                                        | Default | Ceiling                                                    |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------- | ------- | ---------------------------------------------------------- |
| `triggersPerAgent`      | Triggers one agent manifest's `runtime.triggers` declares, checked when it is saved.                                 | 20      | One request body                                           |
| `triggerMinIntervalMs`  | The shortest gap between two runs of one schedule, checked over its next fires when the manifest is saved.           | 60 s    | A number. Floor: 60 s, since a schedule is minute grained. |
| `triggerRunsPerHour`    | Runs one Agent's triggers start or queue in any hour. Later ones are skipped.                                        | 60      | A number                                                   |
| `triggerJitterPercent`  | How far a schedule's fixed offset may move its runs, as a part of its interval.                                      | 10      | 50                                                         |
| `triggerJitterMaxMs`    | The most that offset may be.                                                                                         | 5 min   | A timer                                                    |
| `triggerPromptChars`    | One trigger's `prompt`.                                                                                              | 8,000   | One record entry, escaped                                  |
| `triggerRunRetentionMs` | How long an Agent's runs are kept.                                                                                   | 30 days | A number. Floor: 24 h, since runs dedupe repeated fires.   |
| `wakeMaxAheadMs`        | How far ahead `schedule_wake` may book a session's next turn. It must also be at least `triggerMinIntervalMs` ahead. | 30 days | A number                                                   |
| `wakeNoteChars`         | The longest note a booked wake carries to its turn.                                                                  | 2,000   | One record entry, escaped                                  |
| `webhookBodyBytes`      | The largest delivery a webhook endpoint reads, before it verifies it.                                                | 256 KiB | 960 KiB: the payload goes into one record entry            |

### Memory [#memory]

See [Agent memory](/docs/run/memory). Checked on every write.

| Limit              | What it holds                                                                               | Default | Ceiling                                  |
| ------------------ | ------------------------------------------------------------------------------------------- | ------- | ---------------------------------------- |
| `memoryBytes`      | The largest memory, in UTF-8 bytes.                                                         | 100 KiB | 32 MiB: half a Harness API frame         |
| `memoriesPerAgent` | The most memories one Agent holds.                                                          | 10,000  | A number                                 |
| `memoryIndexLines` | The most lines of the memory index a session pins at its start. Newest memories come first. | 200     | A number                                 |
| `memoryIndexBytes` | The most UTF-8 bytes of that index.                                                         | 25 KiB  | 16 MiB: a quarter of a Harness API frame |

### Flows [#flows]

| Limit                | What it holds                                                                      | Default | Ceiling  |
| -------------------- | ---------------------------------------------------------------------------------- | ------- | -------- |
| `flowConcurrency`    | Effects one [flow](/docs/build/flows) turn runs at once. The rest wait their turn. | 8       | A number |
| `flowMapItems`       | Items one map stage fans out to.                                                   | 1,000   | A number |
| `flowLoopIterations` | Iterations one loop stage runs.                                                    | 100     | A number |

### Agent manifests [#agent-manifests]

What one [agent manifest](/docs/build/agent-manifests) may hold, checked when it is
saved.

| Limit                 | What it holds                                                             | Default | Ceiling                   |
| --------------------- | ------------------------------------------------------------------------- | ------- | ------------------------- |
| `folderFiles`         | Files in one agent manifest.                                              | 2,000   | One request body          |
| `folderBytes`         | Bytes of an agent manifest's files together.                              | 50 MiB  | A number                  |
| `folderTextFileBytes` | One Markdown or JSON file of an agent manifest, which the compiler reads. | 1 MiB   | About 512 MiB: one string |

`npx nylorun check`, `npx nylorun apply`, and `packFolder()` hold a folder to
these defaults whatever the Tenant sets, so raising them helps only a client
that uploads a folder itself, such as Studio's **Upload folder…**.

## Ceilings [#ceilings]

A ceiling is what the Runtime depends on, not configuration:

| Ceiling                             | Value                                                                                                                                                                |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| One string                          | 536,870,888 characters (about 512 MiB), the longest string the JavaScript engine makes. A body the Runtime reads whole, or a file it sends in base64, is one string. |
| One request body, one response body | As many items as fit in one string, each at its smallest JSON.                                                                                                       |
| One record entry                    | 960 KiB. A quoted text there is at most 163,840 characters ("escaped"), since JSON may escape a character to 6 bytes.                                                |
| A Harness API frame                 | 64 MiB, the largest message between the Runtime and a harness.                                                                                                       |
| A timer                             | 2,147,483,647 ms, about 24.8 days, the longest delay a JavaScript timer takes.                                                                                       |
| A number                            | 9,007,199,254,740,991, the largest whole number a JavaScript number holds exactly.                                                                                   |

## Lower limits for one agent [#lower-limits-for-one-agent]

An agent manifest's runtime section may set lower limits for the Agents made
from it:

```json title="runtime.json"
{
  "$schema": "https://docs.nylorun.com/schemas/agent-folder/v1/runtime.json",
  "kind": "pod",
  "limits": {
    "artifacts": { "fileBytes": 26214400 },
    "disk": { "versionEntries": 50000, "versionBytes": 2147483648 }
  }
}
```

| Field                         | Within                                                                                                |
| ----------------------------- | ----------------------------------------------------------------------------------------------------- |
| `limits.artifacts.fileBytes`  | The Tenant's artifact `fileBytes`. The largest file one artifact upload, save, or export may store.   |
| `limits.artifacts.totalBytes` | The Tenant's artifact `totalBytes`. What its sessions' artifacts and its disk versions hold together. |
| `limits.skills.totalBytes`    | The Tenant's skill limit. What one skill's files hold together, for a session to open on it.          |
| `limits.disk.versionEntries`  | The Runtime limit `diskVersionEntries`.                                                               |
| `limits.disk.versionBytes`    | The Runtime limit `diskVersionBytes`.                                                                 |

In an [agent manifest](/docs/build/agent-manifests) this is `runtime.json`; in a
manifest document, its `runtime` section. A value above the Tenant's is refused
when the manifest is saved, naming the limit. A limit left out is the Tenant's, as it is when the limit is checked. The Agent's `limits`
(`client.agents.get(id)`) shows what is in force for it now. See
[Saving manifests](/docs/run/agent-manifests#fields).

## Skill and artifact limits [#skill-and-artifact-limits]

Two other Tenant settings hold sizes, each a document with the same `get` and
`put`:

| Setting   | Limits                                                                                                                                                                                | Default         | Set with                                                        |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | --------------------------------------------------------------- |
| Skills    | `totalBytes`: the most bytes one skill's files hold together. No per-file or file-count limit. A skill past it is `413 limit_exceeded` (`details.skills`) when the manifest is saved. | 2 GiB           | `admin.settings.skills`, `nylorun tenant settings skills`       |
| Artifacts | `fileBytes`: the largest file one upload may store. `totalBytes`: what every artifact version holds together. The view adds `usedBytes`.                                              | 100 MiB, 10 GiB | `admin.settings.artifacts`, `nylorun tenant settings artifacts` |

```ts
await admin.settings.skills.put({ limits: { totalBytes: 4 * 1024 ** 3 } });
```

The Agents' compute settings, such as how many Agents a Tenant holds, are on
[Kubernetes](/docs/deploy/kubernetes#tenant-limits).

## Fixed values [#fixed-values]

Some sizes stay fixed because a dependency or a standard fixes them: a 1 MiB
record entry, the 64 MiB Harness API frame, and the longest JavaScript string
and timer; a token's size, since a bearer token or a capability link arrives in
a request's headers, and a page cursor's, which arrives in a URL; an artifact
name's 255 characters and a folder path's 1,024; a link target's 4,096; W3C
`tracestate`'s 512 characters; a model-facing tool name's 64 characters, which
every provider takes; and a `Content-Type`'s 255. Identifier lengths are part
of the protocol: an Agent's id and a subject 200, an agent manifest's name and
a credential's name 64, a harness id 63, an application key's id and an
issuer's name 32, an idempotency key 256.

## Reference [#reference]

| Call                                        | Endpoint                                                                                                                                                                                               |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `admin.settings.limits.get()`               | [Get the Tenant's Runtime limits](/reference/management/settings/get-the-tenants-runtime-limits)                                                                                                       |
| `admin.settings.limits.put({ limits })`     | [Set the Tenant's Runtime limits](/reference/management/settings/set-the-tenants-runtime-limits)                                                                                                       |
| `admin.settings.skills.get()` / `.put()`    | [Get the Tenant's skill limit](/reference/management/settings/get-the-tenants-skill-limit), [Set the Tenant's skill limit](/reference/management/settings/set-the-tenants-skill-limit)                 |
| `admin.settings.artifacts.get()` / `.put()` | [Get the Tenant's artifact limits](/reference/management/settings/get-the-tenants-artifact-limits), [Set the Tenant's artifact limits](/reference/management/settings/set-the-tenants-artifact-limits) |

## Next step [#next-step]

<Cards>
  <Card title="Models" description="Timeouts, retries, and budgets for model calls." href="/docs/run/models" />

  <Card title="CLI" description="Every command, and the CLI's own waits." href="/docs/run/cli" />
</Cards>
