# Limits and defaults

Every number BasaltDB uses, such as row limits, hold thresholds, timeouts, expiries, batch sizes and how long records are kept.

This page is the numbers. For what BasaltDB will not catch, see [What BasaltDB won't catch](/limits/).

## Rows per action

Rows are counted per action, cascaded rows included. The guard counts them inside your Postgres, so a direct connection with the agent's credential meets the same limits.

| Rows in one action               | What happens                             |
| -------------------------------- | ---------------------------------------- |
| 1 to 10, insert or update        | Goes through. Saved, can be undone.      |
| 11 to 50, insert or update       | Held until you approve it.               |
| Any `DELETE` of up to 50 rows    | Held until you approve it.               |
| More than 50                     | Refused with `ROW_LIMIT_EXCEEDED`.       |
| A split write after you said yes | Batches of up to 50 rows, each one held. |

The limits do not apply to an undo. An undo restores old values and you approve it. See [Rules](/concepts/rules/).

## Reads and time

| What                                    | Default           | Range or note                                                                                                                                                       |
| --------------------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Rows a `query` returns                  | 1,000             | `limits.readRowLimit` in `engine.json`, 1 to 100,000. Over it is `QUERY_TIMEOUT` with the reason `ROW_LIMIT`.                                                       |
| Time for a read (`query`)               | 5 seconds         | `limits.statementTimeoutMs` in `engine.json`, 1 millisecond to 10 minutes. Over it is `QUERY_TIMEOUT` with `TIME_LIMIT`.                                            |
| The agent role's statement timeout      | 30 seconds        | `--statement-timeout` on `basalt init`. Postgres enforces it on every statement that role runs, including a `preview_revert`. A read stops at the lower of the two. |
| Preparing an undo from `request_revert` | 100 seconds       | Over it is `QUERY_TIMEOUT` with `TIME_LIMIT`. Run `basalt revert ... --open` yourself instead.                                                                      |
| Preparing an undo from `basalt revert`  | up to 10 minutes  | The person's CLI is not held to the agent's 100 seconds.                                                                                                            |
| Parameters in one call                  | 1,000             | The `params` array of `query` and `write`.                                                                                                                          |
| SQL in one call                         | 16,384 characters | One statement.                                                                                                                                                      |

Agents never set limits. Change them in `engine.json` or with `basalt init`. See [Configuration](/reference/config/).

## Approvals

| What                                 | Number                                                                                             |
| ------------------------------------ | -------------------------------------------------------------------------------------------------- |
| A hold lasts                         | 24 hours. No answer means blocked (`APPROVAL_EXPIRED`).                                            |
| The agent's wait for you on one call | 90 seconds when it repeats the write with `approvalId`. 0 on a new write. You can set 0 to 110.    |
| Longest wait                         | 110 seconds. It keeps the call in the agent's foreground.                                          |
| Approval code length                 | At most 8,192 characters.                                                                          |
| Waits per turn                       | One. A review can take longer than any wait, and an agent's turn cannot be woken when you approve. |

## Undo

| What                                | Number                                                                                              |
| ----------------------------------- | --------------------------------------------------------------------------------------------------- |
| Time to approve a prepared undo     | 1 hour. After that, `REVERT_EXPIRED`.                                                               |
| An undo applied in one step         | Up to 1,000 lines.                                                                                  |
| A larger undo                       | A plan you sign once. The agent then applies it in batches.                                         |
| Lines per batch                     | 1 to 200. `apply_revert_batch` takes at most 200 line numbers.                                      |
| Time to finish a signed plan        | 24 hours after the signature (`applyBy`).                                                           |
| The agent's wait for your signature | 90 seconds by default, 0 to 110. One wait per turn.                                                 |
| Filters on a preview or request     | At most 20 `runs` and at most 20 `tables`. Over that is `INVALID_ARGUMENT` with `SCOPE_FILTER_CAP`. |
| Intent of an undo                   | 1 to 500 characters.                                                                                |

## Keeping records

| What                           | How long                                                                        |
| ------------------------------ | ------------------------------------------------------------------------------- |
| Old and new values of a change | 30 days. After that a row cannot be restored and is skipped as `VALUES_PRUNED`. |
| The rest of the ledger         | 1 year.                                                                         |
| Heartbeat from the engine      | Every hour. `basalt log` warns after 7 days of silence.                         |
| Passkey unused                 | `basalt log` warns after 90 days, counted from registration if never used.      |
| Active passkeys listed         | At most 100.                                                                    |

See [Change record](/reference/change-record/).

## Lists and text

| What                                 | Number                                                       |
| ------------------------------------ | ------------------------------------------------------------ |
| Items per page of a list             | 50 by default, at most 200. Lists use `cursor`, not offsets. |
| Intent of a run or a write           | At most 500 characters.                                      |
| One next step's `text`               | At most 200 characters.                                      |
| A `personMessage`                    | At most 500 characters, not counting its links.              |
| Longest long link handed to an agent | 1,800 characters (`linkBudget`).                             |

## Setup from your laptop

| What                  | Number                                                         |
| --------------------- | -------------------------------------------------------------- |
| A setup code is valid | 24 hours, and works once.                                      |
| Clock skew allowed    | 5 minutes. A code that claims a time further ahead is refused. |
| Setup code length     | At most 1,500 characters. Name fewer tables if it is longer.   |
| Password of the agent | 256 bits, made on the engine's machine. It never leaves it.    |
| Agent role name       | At most 63 bytes, `<prefix>_agent_<name>`.                     |

## Column classes

| What                                | Number                                                                                  |
| ----------------------------------- | --------------------------------------------------------------------------------------- |
| Sample per column when you classify | Up to 1,000 non-null values, read with your admin connection and dropped after scoring. |
| Dictionary memory                   | 512 MB by default (`pii.maxMemoryMB`).                                                  |
| Dictionary scan                     | 20,000 rows per second by default (`pii.scanRowsPerSecond`).                            |

## The person socket

| What                  | Number                                                       |
| --------------------- | ------------------------------------------------------------ |
| One request           | At most 256 KiB, complete within 10 seconds of the greeting. |
| Connections at once   | 16. The next one waits.                                      |
| A page's request body | At most 16 KiB.                                              |
