# Environment variables

A list of the available environment variables used when running SurrealDB.

Environment variables can be used to tailor the behaviour of a running SurrealDB instance.

Environment variables are divided into four types:

* **SurrealDB environment variables**: environment variables that pertain to the overall running of a SurrealDB server. Example: `SURREAL_DEFAULT_DATABASE`. Includes an [operator and internal config](#operator-and-internal-config) subsection for advanced settings.
* **Command environment variables**: environment variables that can be used in lieu of a command flag. Example: `SURREAL_CAPS_ALLOW_ALL=true surreal start`, equivalent to `surreal start --allow-all`.
* **Storage backend environment variables**: environment variables that pertain to a certain storage backend. Example: `SURREAL_SURREALKV_MAX_SEGMENT_SIZE`.
* **SurrealDB Cloud environment variables**: environment variables that are set via the [Configure instance](/docs/manage/instances/configure.md) sidebar for a SurrealDB Cloud instance.

> [!IMPORTANT]
> Every variable on this page belongs to the `surreal` binary and starts with `SURREAL_`. The [`surrealctl`](/docs/reference/cli/surrealctl/overview.md) control-plane tool reads `SURREALCTL_*` variables instead, and the two prefixes are kept apart deliberately: a database credential such as `SURREAL_TOKEN` is not a control-plane credential, and must not be sent to the SurrealDB Cloud API.

Many environment variables have a maximum value equivalent to the greatest possible `usize`, which is an unsigned integer with a number of bytes depending on the target that the database runs on. For most systems this will be 64 bits, leading to a maximum size of 18_446_744_073_709_551_615 (2<sup>64</sup>), while for 32 bits the maximum will be 4_294_967_296 (2<sup>32</sup>).

## Byte size suffixes

_(since v3.0.0)_

Environment variables that set a size in bytes, such as `SURREAL_HTTP_MAX_SQL_BODY_SIZE` and `SURREAL_WEBSOCKET_MAX_MESSAGE_SIZE`, accept either a raw byte count or a number with a suffix. Suffixes are case-insensitive, and all of them are powers of 1024, so `4GB` and `4GiB` both mean 4,294,967,296 bytes.

| Suffix | Multiplier |
| ------ | ---------- |
| none, `b` | 1 |
| `k`, `kb`, `kib` | 1024 |
| `m`, `mb`, `mib` | 1024<sup>2</sup> |
| `g`, `gb`, `gib` | 1024<sup>3</sup> |

> [!WARNING]
> A value that cannot be parsed is discarded and the default is used instead - the server does not fail to start. On 2.x these variables take a raw byte count only, so a suffixed value such as `16MiB` is silently ignored there and the default remains in effect.

## SurrealDB environment variables

These environment variables can be used to configure a SurrealDB server to configure areas such as the HTTP server and client, limits, telemetry, and so on.

### Batch config

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '40%'}}>Environment variable</th>
      <th scope="col" style={{width: '20%'}}>Default</th>
      <th scope="col" style={{width: '20%'}}>Allowed values</th>
      <th scope="col" style={{width: '20%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_NORMAL_FETCH_SIZE</code></td>
      <td scope="row" data-label="Default">500</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum number of keys that should be scanned at once in general queries.</td>
    </tr>
        <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_EXPORT_BATCH_SIZE</code></td>
      <td scope="row" data-label="Default">1000</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum number of keys that should be scanned at once for export queries.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_COUNT_BATCH_SIZE</code>_(since v2.2.0)_</td>
      <td scope="row" data-label="Default">10,000</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum number of keys that should be scanned at once for count queries.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_INDEXING_BATCH_SIZE</code></td>
      <td scope="row" data-label="Default">250</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum number of keys to scan at once per concurrent indexing batch.</td>
    </tr>
  </tbody>
</table>

### Cache config

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '40%'}}>Environment variable</th>
      <th scope="col" style={{width: '20%'}}>Default</th>
      <th scope="col" style={{width: '20%'}}>Allowed values</th>
      <th scope="col" style={{width: '20%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>
<tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TRANSACTION_CACHE_SIZE</code></td>
      <td scope="row" data-label="Default">10,000</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Specifies the number of items which can be cached within a single transaction.</td>
    </tr>
<tr>
      <td scope="row" data-label="Env var"><code>SURREAL_DATASTORE_CACHE_SIZE</code></td>
      <td scope="row" data-label="Default">1,000</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The number of definitions which can be cached across transactions.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_HNSW_CACHE_SIZE</code></td>
      <td scope="row" data-label="Default">268,435,456 (256 MiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum total size, in bytes, of the HNSW vector cache, shared across all HNSW indexes in the process. This bounds the cached element <em>vectors</em> used for distance computation - it is not a cap on total HNSW memory: the adjacency graph is loaded into resident memory on first use and stays there, outside this budget. Contrast <code>SURREAL_DISKANN_CACHE_SIZE</code>, which does page graph structure.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_DISKANN_CACHE_SIZE</code>_(since v3.1.0)_</td>
      <td scope="row" data-label="Default">268,435,456 (256 MiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum total size, in bytes, of the DISKANN index cache, shared across all DISKANN indexes in the process. DISKANN graph data lives in the key-value store and is paged through this bounded cache. The DISKANN counterpart of <code>SURREAL_HNSW_CACHE_SIZE</code>.</td>
    </tr>
  </tbody>
</table>

### File config

Server-side filesystem access for features that read paths from disk (notably the `mapper()` filter on [`DEFINE ANALYZER`](/docs/reference/query-language/statements/define/analyzer.md)). This is separate from `SURREAL_BUCKET_FOLDER_ALLOWLIST` (below), which gates the experimental [files](/docs/learn/schema-management/files/buckets.md) feature.

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '40%'}}>Environment variable</th>
      <th scope="col" style={{width: '20%'}}>Default</th>
      <th scope="col" style={{width: '20%'}}>Allowed values</th>
      <th scope="col" style={{width: '20%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>
  <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_FILE_ALLOWLIST</code></td>
      <td scope="row" data-label="Default">none (deny all)</td>
      <td scope="row" data-label="Allowed values">Colon-separated paths on Unix; semicolon-separated on Windows</td>
      <td scope="row" data-label="Notes">Directories the server may read when an analyzer uses <code>mapper('&lt;path&gt;')</code>. An empty or unset value denies every path. Each dictionary file must resolve under one of the listed directories. See <a href="/docs/reference/query-language/statements/define/analyzer.md#mapperpath">DEFINE ANALYZER - mapper</a>.</td>
    </tr>
  <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_BUCKET_FOLDER_ALLOWLIST</code></td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">Comma-separated paths</td>
      <td scope="row" data-label="Notes">Specifies a list of paths in which files can be accessed.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_GLOBAL_BUCKET</code></td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">A string</td>
      <td scope="row" data-label="Notes">Specifies the name of a global bucket for file data.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_GLOBAL_BUCKET_ENFORCED</code></td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to enforce a global bucket for file data.</td>
    </tr>
  </tbody>
</table>

### HTTP client config

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '40%'}}>Environment variable</th>
      <th scope="col" style={{width: '20%'}}>Default</th>
      <th scope="col" style={{width: '20%'}}>Allowed values</th>
      <th scope="col" style={{width: '20%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>

  <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MAX_HTTP_REDIRECTS</code></td>
      <td scope="row" data-label="Default">10</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum number of HTTP redirects allowed within http functions.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MAX_HTTP_IDLE_CONNECTIONS_PER_HOST</code></td>
      <td scope="row" data-label="Default">128</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum number of idle HTTP connections to maintain per host.</td>
    </tr>
        <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MAX_HTTP_IDLE_CONNECTIONS</code></td>
      <td scope="row" data-label="Default">1000</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum number of idle HTTP connections to maintain.</td>
    </tr>
<tr>
      <td scope="row" data-label="Env var"><code>SURREAL_HTTP_IDLE_TIMEOUT_SECS</code></td>
      <td scope="row" data-label="Default">90</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The timeout for idle HTTP connections before closing.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_HTTP_CONNECT_TIMEOUT_SECS</code></td>
      <td scope="row" data-label="Default">30</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The timeout for connecting to HTTP endpoints.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_USER_AGENT</code></td>
      <td scope="row" data-label="Default">SurrealDB</td>
      <td scope="row" data-label="Allowed values">A string</td>
      <td scope="row" data-label="Notes">The USER-AGENT string used by HTTP requests.</td>
    </tr>
  </tbody>
</table>

### HTTP server config

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '40%'}}>Environment variable</th>
      <th scope="col" style={{width: '20%'}}>Default</th>
      <th scope="col" style={{width: '20%'}}>Allowed values</th>
      <th scope="col" style={{width: '20%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>

<tr>
      <td scope="row" data-label="Env var"><code>SURREAL_NET_MAX_CONCURRENT_REQUESTS</code></td>
      <td scope="row" data-label="Default">1,048,576</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">How many concurrent network requests can be handled at once</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_HTTP_MAX_ML_BODY_SIZE</code></td>
      <td scope="row" data-label="Default">4,294,967,296 (4 GiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Maximum HTTP body size of the HTTP /ml endpoints. Counted cumulatively across the whole request, not per chunk.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_HTTP_MAX_MCP_BODY_SIZE</code>_(since v3.1.0)_</td>
      <td scope="row" data-label="Default">4,194,304 (4 MiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Maximum HTTP body size of the HTTP <code>/mcp</code> endpoint. See [Embedded MCP](/docs/build/ai-agents/mcp/embedded.md).</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_HTTP_MAX_SQL_BODY_SIZE</code></td>
      <td scope="row" data-label="Default">1,048,576 (1 MiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Maximum HTTP body size of the HTTP /sql endpoint</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_HTTP_MAX_GQL_BODY_SIZE</code>_(since v3.2.0)_</td>
      <td scope="row" data-label="Default">1,048,576 (1 MiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Maximum HTTP body size of the HTTP <code>/gql</code> endpoint. See <a href="/docs/learn/querying/gql/via-http.md">GQL via HTTP</a>.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_HTTP_MAX_API_BODY_SIZE</code></td>
      <td scope="row" data-label="Default">4,194,304 (4 MiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum HTTP body size of the HTTP /api endpoint.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_HTTP_MAX_RPC_BODY_SIZE</code></td>
      <td scope="row" data-label="Default">4,194,304 (4 MiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Maximum HTTP body size of the HTTP /rpc endpoint.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_HTTP_MAX_KEY_BODY_SIZE</code></td>
      <td scope="row" data-label="Default">16,384 (16 KiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Maximum HTTP body size of the HTTP /key endpoints</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_HTTP_MAX_SIGNUP_BODY_SIZE</code></td>
      <td scope="row" data-label="Default">1024 (1 KiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Maximum HTTP body size of the HTTP /signup endpoint.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_HTTP_MAX_IMPORT_BODY_SIZE</code></td>
      <td scope="row" data-label="Default">4,294,967,296 (4 GiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Maximum HTTP body size of the HTTP <code>/import</code> endpoint. Counted cumulatively across the whole request, not per chunk. Also enforced on the gRPC import stream. See [Request size limits](/docs/reference/rest-api/http-protocol.md#request-size-limits).</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_HTTP_MAX_SIGNIN_BODY_SIZE</code></td>
      <td scope="row" data-label="Default">1024 (1 KiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum HTTP body size of the HTTP /signin endpoints</td>
    </tr>
  </tbody>
</table>

> [!NOTE]
> Before SurrealDB 3.3.0, `SURREAL_HTTP_MAX_SIGNUP_BODY_SIZE` and `SURREAL_HTTP_MAX_SIGNIN_BODY_SIZE` were applied to each other's endpoint. Both default to 1 KiB, so no default deployment was affected, but raising one of them had no effect on the endpoint it names and the other endpoint kept returning `413 Payload Too Large`. If you worked around this by tuning the opposite variable, move the value back to the one that matches the endpoint.

### MCP config _(since v3.1.0)_

Used by the built-in [Model Context Protocol](/docs/build/ai-agents/mcp/embedded.md) server (`/mcp` on `surreal start`, `surreal mcp` on stdio). Stdio namespace/database selection uses `SURREAL_MCP_NS` and `SURREAL_MCP_DB` on the [`mcp`](/docs/reference/cli/surrealdb-cli/commands/mcp.md) subcommand.

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '40%'}}>Environment variable</th>
      <th scope="col" style={{width: '20%'}}>Default</th>
      <th scope="col" style={{width: '20%'}}>Allowed values</th>
      <th scope="col" style={{width: '20%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MCP_QUERY_TIMEOUT_SECS</code></td>
      <td scope="row" data-label="Default">60</td>
      <td scope="row" data-label="Allowed values">Seconds (integer); <code>0</code> disables</td>
      <td scope="row" data-label="Notes">Outer timeout on each MCP tool execution.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MCP_MAX_RESULT_BYTES</code></td>
      <td scope="row" data-label="Default">262,144 (256 KiB)</td>
      <td scope="row" data-label="Allowed values">Bytes (integer); <code>0</code> disables</td>
      <td scope="row" data-label="Notes">Maximum serialised tool / resource response size; larger results are truncated with a marker.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MCP_RUN_MAX_ARGS</code></td>
      <td scope="row" data-label="Default">64</td>
      <td scope="row" data-label="Allowed values">A positive integer</td>
      <td scope="row" data-label="Notes">Maximum arguments for a single <code>run</code> tool call.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MCP_PARAMS_MAX_KEYS</code></td>
      <td scope="row" data-label="Default">256</td>
      <td scope="row" data-label="Allowed values">A positive integer</td>
      <td scope="row" data-label="Notes">Maximum top-level keys in MCP parameter / data objects.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MCP_PARAMS_MAX_QL_BYTES</code></td>
      <td scope="row" data-label="Default">4,096 (4 KiB)</td>
      <td scope="row" data-label="Allowed values">A positive integer; values ≤ 0 fall back to the default</td>
      <td scope="row" data-label="Notes">Maximum byte length of a single <code>$ql</code> SurrealQL pass-through string inside a <code>*_data</code> payload.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MCP_SCHEMA_RESOURCE_MAX_TABLES</code></td>
      <td scope="row" data-label="Default">200</td>
      <td scope="row" data-label="Allowed values">A positive integer; values ≤ 0 fall back to the default</td>
      <td scope="row" data-label="Notes">Maximum tables the database-level schema resource enriches with per-table fields / indexes / events. Tables beyond the cap keep a bare <code>DEFINE TABLE</code> and the body includes a <code>tables_truncated_at</code> marker.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MCP_ALLOWED_HOSTS</code> _(since v3.2.1)_</td>
      <td scope="row" data-label="Default">loopback only (<code>localhost</code>, <code>127.0.0.1</code>, <code>::1</code>)</td>
      <td scope="row" data-label="Allowed values">Comma-separated exact hostnames</td>
      <td scope="row" data-label="Notes">Hostnames accepted in the HTTP <code>Host</code> header for <code>/mcp</code> (DNS-rebinding guard). A non-empty list <strong>replaces</strong> the loopback default, so include <code>localhost</code> yourself if you still need it. Entries without a port match any port. Ignored when <code>SURREAL_MCP_ALLOW_ALL_HOSTS</code> is set.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MCP_ALLOW_ALL_HOSTS</code> _(since v3.2.1)_</td>
      <td scope="row" data-label="Default"><code>false</code></td>
      <td scope="row" data-label="Allowed values"><code>true</code> / <code>1</code> to enable</td>
      <td scope="row" data-label="Notes">Disables the <code>Host</code>-header allowlist (accept any <code>Host</code>). Escape hatch for a trusted proxy or load balancer. Takes precedence over <code>SURREAL_MCP_ALLOWED_HOSTS</code>.</td>
    </tr>
  </tbody>
</table>

### GQL config _(since v3.2.0)_

Resource limits for [ISO GQL](/docs/learn/querying/gql/overview.md) `MATCH` execution. Errors name the limit when it is exceeded. From **3.3.0**, GQL is enabled by default; on **3.2.x**, enable it with [`--allow-experimental gql`](/docs/reference/cli/surrealdb-cli/commands/start.md#experimental-capabilities).

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '40%'}}>Environment variable</th>
      <th scope="col" style={{width: '20%'}}>Default</th>
      <th scope="col" style={{width: '20%'}}>Allowed values</th>
      <th scope="col" style={{width: '20%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_GQL_MAX_PATH_ROWS</code></td>
      <td scope="row" data-label="Default">1,000,000</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Per source row, bounds live and emitted rows during variable-length path expansion in a GQL <code>MATCH</code>.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_GQL_MAX_JOIN_BUILD_ROWS</code></td>
      <td scope="row" data-label="Default">1,000,000</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Bounds the in-memory build side of hash joins between GQL match patterns (and distinct-operator working sets).</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_GQL_MAX_OUTPUT_ROWS</code></td>
      <td scope="row" data-label="Default">1,000,000</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Bounds cumulative rows emitted by GQL hash-join operators (including cross joins).</td>
    </tr>
  </tbody>
</table>

### Limits config

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '40%'}}>Environment variable</th>
      <th scope="col" style={{width: '20%'}}>Default</th>
      <th scope="col" style={{width: '20%'}}>Allowed values</th>
      <th scope="col" style={{width: '20%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>

    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_EXTERNAL_SORTING_BUFFER_LIMIT</code></td>
      <td scope="row" data-label="Default">50000</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The number of result records which will trigger on-disk sorting.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_STRING_SIMILARITY_LIMIT</code></td>
      <td scope="row" data-label="Default">16384</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum input string length for similarity/distance functions</td>
    </tr>
     <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_GENERATION_ALLOCATION_LIMIT</code></td>
      <td scope="row" data-label="Default">1,048,576</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Limits memory allocation for certain built-in functions (e.g., string::replace) to avoid uncontrolled memory usage. Default is 1,048,576 bytes (computed as 2<sup>20</sup>).</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_IDIOM_RECURSION_LIMIT</code></td>
      <td scope="row" data-label="Default">256</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum recursive idiom path depth allowed.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MAX_COMPUTATION_DEPTH</code></td>
      <td scope="row" data-label="Default">120</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Specifies how deep recursive computation will go before erroring.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MAX_CONCURRENT_TASKS</code></td>
      <td scope="row" data-label="Default">64</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Specifies how many concurrent jobs can be buffered in the worker channel.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MAX_OBJECT_PARSING_DEPTH</code></td>
      <td scope="row" data-label="Default">100</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Specifies how deep the parser will parse nested objects and arrays in a query.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MAX_ORDER_LIMIT_PRIORITY_QUEUE_SIZE</code>_(since v2.2.0)_</td>
      <td scope="row" data-label="Default">1000</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum size of the priority queue triggering usage of the priority queue for the result collector.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MAX_QUERY_PARSING_DEPTH</code></td>
      <td scope="row" data-label="Default">20</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Specifies how deep the parser will parse recursive queries (queries within queries).</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_OPERATOR_BUFFER_SIZE</code></td>
      <td scope="row" data-label="Default">2</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The number of batches each operator buffers ahead of downstream demand. Set to 0 to disable operator-level pipeline buffering.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_REGEX_SIZE_LIMIT</code></td>
      <td scope="row" data-label="Default">10,485,760 (10 MiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Limits the maximum allowed size (in bytes) for regular expressions. This prevents excessive memory consumption when building complex or very large regex patterns.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TRANSACTION_MAX_WRITE_KEYS</code>_(since v3.2.4)_</td>
      <td scope="row" data-label="Default">0 (disabled)</td>
      <td scope="row" data-label="Allowed values">A <code>u64</code>; <code>0</code> disables</td>
      <td scope="row" data-label="Notes">Maximum number of key writes a single statement transaction may buffer before it is aborted and rolled back. Cascaded deletes, full-text index maintenance, graph-edge cleanup, and commit-time changefeed / live-query events all count toward the limit; each range delete counts as one write. Tripping the guard poisons the transaction so an explicit client <code>COMMIT</code> cannot persist a partial statement. Internal maintenance transactions (index builds, compaction, GC) are not bounded. On TiKV, range deletes may expand further inside the storage layer - size distributed clusters with both this limit and <code>SURREAL_TIKV_DELR_MAX_KEYS</code> in mind. Scale / multi-node deployments often use a limit in the 50,000-100,000 range; leave at <code>0</code> for typical single-node use.</td>
    </tr>
  </tbody>
</table>

### Runtime config

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '40%'}}>Environment variable</th>
      <th scope="col" style={{width: '20%'}}>Default</th>
      <th scope="col" style={{width: '20%'}}>Allowed values</th>
      <th scope="col" style={{width: '20%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_RUNTIME_MAX_BLOCKING_THREADS</code></td>
      <td scope="row" data-label="Default">512</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Number of threads which can be started for blocking operations.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_RUNTIME_STACK_SIZE</code></td>
      <td scope="row" data-label="Default">10,485,760 (10 MiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Runtime thread memory stack size. Default stack size is doubled if compiled from source in Debug mode.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_RUNTIME_WORKER_THREADS</code></td>
      <td scope="row" data-label="Default">Number of CPU cores (minimum 4)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Number of runtime worker threads used to start.</td>
    </tr>
  </tbody>
</table>

### Scripting config

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '40%'}}>Environment variable</th>
      <th scope="col" style={{width: '20%'}}>Default</th>
      <th scope="col" style={{width: '20%'}}>Allowed values</th>
      <th scope="col" style={{width: '20%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SCRIPTING_MAX_STACK_SIZE</code></td>
      <td scope="row" data-label="Default">262_144 (256 KiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Maximum stack size of the JavaScript function runtime.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SCRIPTING_MAX_MEMORY_LIMIT</code></td>
      <td scope="row" data-label="Default">2,097,152 (2 MiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Maximum memory limit of the JavaScript function runtime.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SCRIPTING_MAX_TIME_LIMIT</code></td>
      <td scope="row" data-label="Default">5000 (5000 milliseconds or 5 seconds)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Maximum allowed time in milliseconds that a JavaScript function is allowed to run for.</td>
    </tr>
  </tbody>
</table>

### Security config

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '40%'}}>Environment variable</th>
      <th scope="col" style={{width: '20%'}}>Default</th>
      <th scope="col" style={{width: '20%'}}>Allowed values</th>
      <th scope="col" style={{width: '20%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_INSECURE_FORWARD_ACCESS_ERRORS</code></td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Forward all signup/signin/authenticate query errors to a client performing authentication. Do not use in production.</td>
    </tr>
  </tbody>
</table>

### Surrealism config

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '40%'}}>Environment variable</th>
      <th scope="col" style={{width: '20%'}}>Default</th>
      <th scope="col" style={{width: '20%'}}>Allowed values</th>
      <th scope="col" style={{width: '20%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_LAZY_SURREALISM</code>_(since v3.1.0)_</td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to lazy-load Surrealism modules instead of eagerly compiling them at server startup.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SURREALISM_CACHE_SIZE</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Default">100</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The number of surrealism modules which can be cached across transactions.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SURREALISM_MAX_POOL_SIZE</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Default">8</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Per-module controller pool size ceiling for Surrealism WASM modules.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SURREALISM_MAX_MEMORY</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Default">None (unlimited)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Per-module WASM linear memory ceiling in bytes.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SURREALISM_MAX_EXECUTION_TIME</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Default">None (unlimited)</td>
      <td scope="row" data-label="Allowed values">A u64 (milliseconds)</td>
      <td scope="row" data-label="Notes">Per-invocation execution time ceiling for Surrealism WASM modules.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SURREALISM_MAX_KV_ENTRIES</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Default">None (unlimited)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Per-module KV store entry count ceiling.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SURREALISM_MAX_KV_VALUE_BYTES</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Default">None (unlimited)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Per-module KV store maximum value size in bytes.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SURREALISM_LOG_LEVEL</code>_(since v3.1.0)_</td>
      <td scope="row" data-label="Default">debug</td>
      <td scope="row" data-label="Allowed values">none, full, error, warn, info, debug, trace</td>
      <td scope="row" data-label="Notes">Controls the tracing level at which Surrealism module stdout is emitted.</td>
    </tr>
  </tbody>
</table>

### Telemetry config

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '40%'}}>Environment variable</th>
      <th scope="col" style={{width: '20%'}}>Default</th>
      <th scope="col" style={{width: '20%'}}>Allowed values</th>
      <th scope="col" style={{width: '20%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TELEMETRY_DISABLE_METRICS</code></td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to disable sending metrics to the GRPC OTEL collector.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TELEMETRY_DISABLE_TRACING</code></td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to disable sending traces to the GRPC OTEL collector.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TELEMETRY_NAMESPACE</code></td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">A string</td>
      <td scope="row" data-label="Notes">If set then use this as value for the namespace label when sending telemetry</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TELEMETRY_PROVIDER</code></td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">otlp</td>
      <td scope="row" data-label="Notes">If set to "otlp" then telemetry is sent to the GRPC OTEL collector.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TOKIO_CONSOLE_ENABLED</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to enable [tokio console](https://github.com/tokio-rs/console).</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TOKIO_CONSOLE_RETENTION</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Default">60</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">How long, in seconds, to retain data for completed events.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TOKIO_CONSOLE_SOCKET_ADDR</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">String to a socket address</td>
      <td scope="row" data-label="Notes">The socket address that Tokio Console will bind to.</td>
    </tr>
  </tbody>
</table>

### WebSocket config

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '40%'}}>Environment variable</th>
      <th scope="col" style={{width: '20%'}}>Default</th>
      <th scope="col" style={{width: '20%'}}>Allowed values</th>
      <th scope="col" style={{width: '20%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_WEBSOCKET_MAX_MESSAGE_SIZE</code></td>
      <td scope="row" data-label="Default">134,217,728 (128 MiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum WebSocket message size.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_WEBSOCKET_MAX_WRITE_BUFFER_SIZE</code></td>
      <td scope="row" data-label="Default">Greatest possible usize value</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum write buffer size before backpressure is applied.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_WEBSOCKET_READ_BUFFER_SIZE</code></td>
      <td scope="row" data-label="Default">131,072 (128 KiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The size of the read buffer for WebSocket connections. This controls how much data can be buffered when reading from WebSocket connections. Larger values can improve performance for high-throughput connections but consume more memory per connection.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_WEBSOCKET_WRITE_BUFFER_SIZE</code></td>
      <td scope="row" data-label="Default">131,072 (128 KiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The size of the write buffer for WebSocket connections. This controls how much data can be buffered when writing to WebSocket connections. Larger values can improve performance for high-throughput connections but consume more memory per connection.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_WEBSOCKET_RESPONSE_BUFFER_SIZE</code></td>
      <td scope="row" data-label="Default">0</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">How many responses can be buffered when delivering to the client.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_WEBSOCKET_RESPONSE_CHANNEL_SIZE</code></td>
      <td scope="row" data-label="Default">100</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Number of messages that can be queued for sending via WebSocket.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_WEBSOCKET_RESPONSE_FLUSH_PERIOD</code></td>
      <td scope="row" data-label="Default">3</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">How often (in milliseconds) any buffered responses are flushed to the WebSocket client.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MAX_TRANSACTIONS_PER_CONNECTION</code>_(since v3.2.2)_</td>
      <td scope="row" data-label="Default">64</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Maximum concurrently open client-managed transactions (<code>begin</code> RPC) on a WebSocket connection's implicit default session. Further <code>begin</code> calls return <code>Too many open transactions</code> until a slot is freed by <code>commit</code>, <code>cancel</code>, <code>reset</code>, or disconnect. Does not apply to attached sessions (see <code>SURREAL_MAX_TRANSACTIONS_PER_SESSION</code>).</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MAX_TRANSACTIONS_PER_SESSION</code>_(since v3.2.2)_</td>
      <td scope="row" data-label="Default">64</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Maximum concurrently open client-managed transactions within a single attached WebSocket session. Counted per session and independent of the connection default-session limit. Detaching or resetting a session cancels its open transactions and frees their slots.</td>
    </tr>
  </tbody>
</table>

### Operator and internal config

_(since v3.2.0)_

These settings are for operators, benchmarks, and advanced debugging - not typical application configuration. They are documented so core contributors and self-hosted deployments can find configuration options that already exist in the engine. Changing them can affect performance, reproducibility, or live-query behaviour; leave defaults in place unless you have a specific reason to tune them.

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '40%'}}>Environment variable</th>
      <th scope="col" style={{width: '20%'}}>Default</th>
      <th scope="col" style={{width: '20%'}}>Allowed values</th>
      <th scope="col" style={{width: '20%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_RAND_SEED</code></td>
      <td scope="row" data-label="Default">none (non-deterministic)</td>
      <td scope="row" data-label="Allowed values">A <code>u64</code></td>
      <td scope="row" data-label="Notes">Seeds the engine-wide RNG for reproducible runs in benchmarks and tests. Do not use in production.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_LIVE_QUERY_ENGINE</code></td>
      <td scope="row" data-label="Default"><code>inline</code></td>
      <td scope="row" data-label="Allowed values"><code>inline</code>, <code>router</code></td>
      <td scope="row" data-label="Notes">Selects the live-query execution engine. <code>inline</code> is the historical behaviour; <code>router</code> decouples write cost from subscriber count (experimental rollout).</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_LIVE_QUERY_RETENTION</code></td>
      <td scope="row" data-label="Default">1h</td>
      <td scope="row" data-label="Allowed values">A duration</td>
      <td scope="row" data-label="Notes">How long the router engine retains live-query event history for subscriber resume. Only applies when <code>SURREAL_LIVE_QUERY_ENGINE=router</code>.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_HNSW_BUILD_SEED</code></td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">A <code>u64</code></td>
      <td scope="row" data-label="Notes">Seeds HNSW index construction for reproducible graph layouts in benchmarks. Do not use in production.</td>
    </tr>
  </tbody>
</table>

### Other environment variables

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '40%'}}>Environment variable</th>
      <th scope="col" style={{width: '20%'}}>Default</th>
      <th scope="col" style={{width: '20%'}}>Allowed values</th>
      <th scope="col" style={{width: '20%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_BUILD_METADATA</code></td>
      <td scope="row" data-label="Default">Automatically populated</td>
      <td scope="row" data-label="Allowed values">A string</td>
      <td scope="row" data-label="Notes">The version identifier of this build. Defaults to the CARGO_PKG_VERSION environment variable if not specified.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_DATASTORE_AOL</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Default">never</td>
      <td scope="row" data-label="Allowed values">never|sync|async</td>
      <td scope="row" data-label="Notes">Append-only log mode. Only used by the memory engine.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_DATASTORE_PERSIST</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">String to a file path</td>
      <td scope="row" data-label="Notes">Filesystem path for persistence. Only used by the memory engine.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_DATASTORE_RETENTION</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Default">0 (unlimited)</td>
      <td scope="row" data-label="Allowed values">A duration</td>
      <td scope="row" data-label="Notes">Version retention period as a duration string. Used by memory and surrealkv engines.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_DATASTORE_SNAPSHOT</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Default">never</td>
      <td scope="row" data-label="Allowed values">never|duration</td>
      <td scope="row" data-label="Notes">Snapshot interval. Only used by the memory engine.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_DATASTORE_SYNC_DATA</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Default">every</td>
      <td scope="row" data-label="Allowed values">never|every|duration</td>
      <td scope="row" data-label="Notes">The sync mode for the database. Used by memory, rocksdb, and surrealkv engines.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_DATASTORE_VERSIONED</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true|false|0|1</td>
      <td scope="row" data-label="Notes">Whether MVCC versioning is enabled. Used by memory and surrealkv engines.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_MEMORY_THRESHOLD</code></td>
      <td scope="row" data-label="Default">0</td>
      <td scope="row" data-label="Allowed values">A usize or suffixed integer</td>
      <td scope="row" data-label="Notes">Configuring the memory threshold which can be used across the programme to check if the amount of memory available to the programme is lower than required. The value can be specified as bytes (b, or without any suffix), kibibytes (k, kb, or kib), mebibytes (m, mb, or mib), or gibibytes (g, gb, or gib). If the environment variable is not specified, then the threshold is not used, and no memory limit is enabled.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_REGEX_CACHE_SIZE</code></td>
      <td scope="row" data-label="Default">1000</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The number of computed regexes which can be cached in the engine.</td>
    </tr>
  </tbody>
</table>

## Command environment variables

Many of the arguments passed into [the CLI](/docs/reference/cli/surrealdb-cli/commands/start.md) can be set using the above environment variables instead.

As each of these environment variables correspond to a flag or a required argument passed into a command, it is good practice to put together a command that matches the environment variables you wish to set. Once the database server conforms to your expected behaviour, you can then pull out the values passed into each flag for your environment variables.

For example, take the following command to start the database.

```bash
surreal start --user root --pass secret --allow-net --deny-funcs "crypto::md5, http::post, http::delete"
```

If we now wanted to use environment variables instead of the `--allow-net` and `--deny-funcs` flags, we would use the `SURREAL_CAPS_ALLOW_NET` and `SURREAL_CAPS_DENY_FUNC` environment variables.

As the `--allow-net` flag was passed in without a following value, the same will be the case with the `SURREAL_CAPS_ALLOW_NET` environment variable, becoming `SURREAL_CAPS_ALLOW_NET=`. The `--deny-funcs` flag can also be used on its own to deny execution of all functions, but in this case is followed by a string to indicate which exact functions are not allowed to be executed. As such, the `SURREAL_CAPS_DENY_FUNC` environment variable must also be followed by a string, becoming `SURREAL_CAPS_DENY_FUNC="crypto::md5, http::post, http::delete"`.

The command would then look like the following:

**Bash**

```bash
SURREAL_CAPS_ALLOW_NET
SURREAL_CAPS_DENY_FUNC="crypto::md5, http::post, http::delete"
surreal start --user root --pass secret
```

**PowerShell**

```powershell
$env:SURREAL_CAPS_ALLOW_NET
$env:SURREAL_CAPS_DENY_FUNC="crypto::md5, http::post, http::delete"
surreal start --user root --pass secret
```

A command environment variable that takes a boolean will be set to true if the flag is present, and following it with `true` will cause an error.

For example, the `SURREAL_CAPS_ALLOW_ALL` environment variable is used to set whether to allow all capabilities such as scripting and allowing network access. The flag `--allow-all` is all that is needed to set to `true`. But as an environment variable, the value `true` must be included to override its default `false` value.

```bash title="SURREAL_CAPS_ALLOW_ALL example"
# set to default false
surreal start

# Same, but implicitly shown
SURREAL_CAPS_ALLOW_ALL=false surreal start

# Set to true
SURREAL_CAPS_ALLOW_ALL=true surreal start

# Set to true
surreal start --allow-all

# Error: only --allow-all needed to set to true
surreal start --allow-all true
```

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '25%'}}>Environment variable</th>
      <th scope="col" style={{width: '15%'}}>Command arg</th>
      <th scope="col" style={{width: '12%'}}>For command(s)</th>
      <th scope="col" style={{width: '12%'}}>Default</th>
      <th scope="col" style={{width: '18%'}}>Allowed values</th>
      <th scope="col" style={{width: '18%'}}>Details</th>
    </tr>
  </thead>
  <tbody>
  <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ASYNC_EVENT_PROCESSING_INTERVAL</code>_(since v3.0.0)_ </td>
      <td scope="row" data-label="Command arg"><code>async-event-processing-interval</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">5s</td>
      <td scope="row" data-label="Allowed values">A duration</td>
      <td scope="row" data-label="Notes">The interval at which to process async events.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_AUTH_LEVEL</code></td>
      <td scope="row" data-label="Command arg"><code>auth-level</code></td>
      <td scope="row" data-label="Command">`export`, `import`, `sql`</td>
      <td scope="row" data-label="Default">root</td>
      <td scope="row" data-label="Allowed values">root, namespace, ns, database, db</td>
      <td scope="row" data-label="Notes">Authentication level to use when connecting.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_BIND</code></td>
      <td scope="row" data-label="Command arg"><code>bind</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">127.0.0.1:8000</td>
      <td scope="row" data-label="Allowed values">String to an address</td>
      <td scope="row" data-label="Notes">The hostname or IP address(es) to listen for connections on.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_POSTGRES_BIND</code></td>
      <td scope="row" data-label="Command arg"><code>postgres-bind</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">(disabled)</td>
      <td scope="row" data-label="Allowed values">String to an address</td>
      <td scope="row" data-label="Notes">The hostname or IP address to listen for <a href="/docs/reference/rest-api/postgres-protocol.md">Postgres wire protocol</a> connections on.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_CAPS_ALLOW_ALL</code></td>
      <td scope="row" data-label="Command arg"><code>allow-all</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Allow all capabilities.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_CAPS_ALLOW_ARBITRARY_QUERY</code></td>
      <td scope="row" data-label="Command arg"><code>allow-arbitrary-query</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">guest, record, system (comma-separated)</td>
      <td scope="row" data-label="Notes">Allows arbitrary queries to be used by user groups except when specifically denied. Alternatively, you can provide a comma-separated list of user groups to allow specifically denied user groups to prevail over any other allowed user group.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_CAPS_ALLOW_EVAL_QUERY</code>_(since v3.2.0)_</td>
      <td scope="row" data-label="Command arg"><code>allow-eval-query</code></td>
      <td scope="row" data-label="Command">`start`, `sql`</td>
      <td scope="row" data-label="Default">none (denied for all subjects)</td>
      <td scope="row" data-label="Allowed values">guest, record, system (comma-separated)</td>
      <td scope="row" data-label="Notes">Allow <code>eval::surql</code> and <code>eval::gql</code> for listed subject groups. Not enabled by <code>--allow-all</code>. Still subject to <a href="/docs/learn/security/authorization/capabilities.md#arbitrary-queries">arbitrary-query</a> restrictions - <code>--deny-arbitrary-query</code> blocks <code>eval</code> for that subject even when eval is allowed here. For remote clients, set on the <code>start</code> process only. See <a href="/docs/reference/cli/surrealdb-cli/commands/sql.md#capabilities-and-remote-connections">Capabilities and remote connections</a>.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_CAPS_ALLOW_EXPERIMENTAL</code></td>
      <td scope="row" data-label="Command arg"><code>allow-experimental</code></td>
      <td scope="row" data-label="Command">`start`, `sql`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">files, surrealism (comma-separated; legacy <code>gql</code> accepted but unused from 3.3.0)</td>
      <td scope="row" data-label="Notes">Allow execution of experimental features. For remote clients, set on the <code>start</code> process. On <code>surreal sql</code>, affects embedded engines and REPL parse validation only. See <a href="/docs/reference/cli/surrealdb-cli/commands/start.md#experimental-capabilities">experimental capabilities</a>. From 3.3.0, ISO GQL is on by default and does not need this variable.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_CAPS_ALLOW_FUNC</code></td>
      <td scope="row" data-label="Command arg"><code>allow-funcs</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">all functions allowed</td>
      <td scope="row" data-label="Allowed values">Empty, <code>*</code>, or comma-separated function paths</td>
      <td scope="row" data-label="Notes">Allow execution of all functions except for functions that are specifically denied. Set to an empty value or <code>*</code> to allow all functions. Use a comma-separated list (for example, <code>array,string::len,http::get</code>) to allow specific function families or names. Values such as <code>true</code> are not valid. The environment variable name is singular (<code>FUNC</code>), matching the <code>--allow-funcs</code> flag.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_CAPS_ALLOW_GUESTS</code></td>
      <td scope="row" data-label="Command arg"><code>allow-guests</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">true</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Allow guest users to execute queries.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_CAPS_ALLOW_NET</code></td>
      <td scope="row" data-label="Command arg"><code>allow-net</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">Comma-separated list of paths</td>
      <td scope="row" data-label="Notes">Allow all or certain outbound network access.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_CAPS_ALLOW_SCRIPT</code></td>
      <td scope="row" data-label="Command arg"><code>allow-scripting</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">true</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Allow execution of embedded scripting functions.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_CAPS_ALLOW_INSECURE_STORABLE_CLOSURES</code>_(since v2.5.0)_</td>
      <td scope="row" data-label="Command arg"><code>allow-insecure-storable-closures</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Takes a boolean. Prevents closures from being stored, which eliminates a potential attack surface. For version 2.5.0, this can still be allowed by using this capability.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_CAPS_DENY_ALL</code></td>
      <td scope="row" data-label="Command arg"><code>deny-all</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Deny all capabilities.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_CAPS_DENY_EVAL_QUERY</code>_(since v3.2.0)_</td>
      <td scope="row" data-label="Command arg"><code>deny-eval-query</code></td>
      <td scope="row" data-label="Command">`start`, `sql`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">guest, record, system (comma-separated)</td>
      <td scope="row" data-label="Notes">Deny <code>eval::surql</code> and <code>eval::gql</code> for listed subject groups. Deny prevails over allow at the same specificity. For remote clients, set on the <code>start</code> process.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_CAPS_DENY_FUNC</code></td>
      <td scope="row" data-label="Command arg"><code>deny-funcs</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false, comma-separated list</td>
      <td scope="row" data-label="Notes">Deny execution of all or certain functions.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_CAPS_DENY_GUESTS</code></td>
      <td scope="row" data-label="Command arg"><code>deny-guests</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">true</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Deny guest users from executing queries.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_CAPS_DENY_NET</code></td>
      <td scope="row" data-label="Command arg"><code>deny-net</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">true</td>
      <td scope="row" data-label="Allowed values">true, false, comma-separated list</td>
      <td scope="row" data-label="Notes">Deny all or certain outbound access paths.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_CAPS_DENY_SCRIPT</code></td>
      <td scope="row" data-label="Command arg"><code>deny-scripting</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">true</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Deny execution of embedded scripting functions.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_CHANGEFEED_GC_INTERVAL</code></td>
      <td scope="row" data-label="Command arg"><code>changefeed-gc-interval</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">30s</td>
      <td scope="row" data-label="Allowed values">A duration</td>
      <td scope="row" data-label="Notes">The interval at which to perform changefeed garbage collection.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_CLIENT_IP</code></td>
      <td scope="row" data-label="Command arg"><code>client-ip</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">none, socket, CF-Connecting-IP, Fly-Client-IP, True-Client-IP, X-Real-IP, X-Forwarded-For, Forwarded</td>
      <td scope="row" data-label="Notes">The method of detecting the client's IP address. _(since v3.1.0)_ <code>Forwarded</code> parses the RFC 7239 <code>Forwarded</code> header (<code>for=</code> parameter).</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_DATABASE</code></td>
      <td scope="row" data-label="Command arg"><code>database</code></td>
      <td scope="row" data-label="Command">`sql`</td>
      <td scope="row" data-label="Default">main</td>
      <td scope="row" data-label="Allowed values">A string</td>
      <td scope="row" data-label="Notes">The database selected when starting the REPL.</td>
    </tr>
<tr>
      <td scope="row" data-label="Env var"><code>SURREAL_DATABASE</code></td>
      <td scope="row" data-label="Command arg"><code>database</code></td>
      <td scope="row" data-label="Command">`export`, `import`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">A string</td>
      <td scope="row" data-label="Notes">The database selected for the import or export.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_DEFAULT_DATABASE</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Command arg"><code>default-database</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">main</td>
      <td scope="row" data-label="Allowed values">A string</td>
      <td scope="row" data-label="Notes">The default database to use when starting a SurrealDB instance.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_DEFAULT_NAMESPACE</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Command arg"><code>default-namespace</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">main</td>
      <td scope="row" data-label="Allowed values">A string</td>
      <td scope="row" data-label="Notes">The default namespace to use when starting a SurrealDB instance.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_DURABLE_SESSIONS</code>_(since v3.2.2)_</td>
      <td scope="row" data-label="Command arg"><code>durable-sessions</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Persist client-attached HTTP RPC sessions in the datastore so they survive restarts and can be resumed on any node sharing the storage. Off by default. WebSocket sessions are not durable. The persisted copy includes authentication state and is stored unencrypted. See <a href="/docs/reference/cli/surrealdb-cli/commands/start.md#durable-http-rpc-sessions">Durable HTTP RPC sessions</a>.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_DURABLE_SESSION_GC_INTERVAL</code>_(since v3.2.2)_</td>
      <td scope="row" data-label="Command arg"><code>durable-session-gc-interval</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">60s</td>
      <td scope="row" data-label="Allowed values">A duration; <code>0</code> disables the background sweep</td>
      <td scope="row" data-label="Notes">How often expired durable HTTP RPC sessions are purged. Lazy expiry on load still applies when the sweep is disabled. Only meaningful when durable sessions are enabled.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_DURABLE_SESSION_TTL</code>_(since v3.2.2)_</td>
      <td scope="row" data-label="Command arg"><code>durable-session-ttl</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">24h</td>
      <td scope="row" data-label="Allowed values">A duration greater than zero</td>
      <td scope="row" data-label="Notes">Idle lifetime of a persisted HTTP RPC session; each use refreshes the expiry (sliding TTL). Must be greater than zero when durable sessions are enabled.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_HIDE_WELCOME</code></td>
      <td scope="row" data-label="Command arg"><code>hide-welcome</code></td>
      <td scope="row" data-label="Command">`sql`</td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to show the welcome message when starting the REPL.</td>
    </tr>
<tr>
      <td scope="row" data-label="Env var"><code>SURREAL_IMPORT_FILE</code></td>
      <td scope="row" data-label="Command arg"><code>import-file</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">A file path</td>
      <td scope="row" data-label="Notes">Path to a SurrealQL file that will be imported when starting the server.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_INDEX_COMPACTION_INTERVAL</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Command arg"><code>index-compaction-interval</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">5s</td>
      <td scope="row" data-label="Allowed values">A duration</td>
      <td scope="row" data-label="Notes">The interval at which to compact queued index updates. Writes to a full-text, count, or vector index enqueue pending updates that a background task folds into the index; this controls how often that task runs. One node in a cluster performs the work for the whole cluster. Lengthening the interval allows the pending backlog to grow, which increases the work each subsequent query must do to read through it.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_KEY</code></td>
      <td scope="row" data-label="Command arg"><code>key</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">A string 16, 24, or 32 bytes long</td>
      <td scope="row" data-label="Notes">Encryption key to use for on-disk encryption. Not currently in use.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_KVS_CA</code></td>
      <td scope="row" data-label="Command arg"><code>kvs-ca</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">String to a path</td>
      <td scope="row" data-label="Notes">Path to the CA file used when connecting to the remote KV store.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_KVS_CRT</code></td>
      <td scope="row" data-label="Command arg"><code>kvs-crt</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">String to a path</td>
      <td scope="row" data-label="Notes">Path to the certificate file used when connecting to the remote KV store.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_KVS_KEY</code></td>
      <td scope="row" data-label="Command arg"><code>kvs-key</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">String to a path</td>
      <td scope="row" data-label="Notes">Path to the private key file used when connecting to the remote KV store.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_LAZY_SURREALISM</code>_(since v3.1.0)_</td>
      <td scope="row" data-label="Command arg"><code>lazy-surrealism</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to lazy-load Surrealism modules instead of eagerly compiling them at server startup.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_LOG</code></td>
      <td scope="row" data-label="Command arg"><code>log</code></td>
      <td scope="row" data-label="Command">`start`, `fix`</td>
      <td scope="row" data-label="Default">info</td>
      <td scope="row" data-label="Allowed values">none, full, error, warn, info, debug, trace</td>
      <td scope="row" data-label="Notes">The logging level for the database server.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_LOG_FILE_ENABLED</code>_(since v2.4.0)_</td>
      <td scope="row" data-label="Command arg"><code>log-file-enabled</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Toggles file output.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_LOG_FILE_FORMAT</code>_(since v2.4.0)_</td>
      <td scope="row" data-label="Command arg"><code>log-file-format</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">text, json</td>
      <td scope="row" data-label="Notes">The format for log file output.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_LOG_FILE_LEVEL</code>_(since v2.4.0)_</td>
      <td scope="row" data-label="Command arg"><code>log-file-level</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">none, full, error, warn, info, debug, trace</td>
      <td scope="row" data-label="Notes">Override the logging level for file output</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_LOG_FILE_NAME</code>_(since v2.4.0)_</td>
      <td scope="row" data-label="Command arg"><code>log-file-name</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">surrealdb.log</td>
      <td scope="row" data-label="Allowed values">String to a file</td>
      <td scope="row" data-label="Notes">Filename for logs (default: `surrealdb.log`)</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_LOG_FILE_PATH</code>_(since v2.4.0)_</td>
      <td scope="row" data-label="Command arg"><code>log-file-path</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">logs</td>
      <td scope="row" data-label="Allowed values">String to a path</td>
      <td scope="row" data-label="Notes">Sets the directory for logs</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_LOG_FILE_ROTATION</code>_(since v2.4.0)_</td>
      <td scope="row" data-label="Command arg"><code>log-file-rotation</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">daily</td>
      <td scope="row" data-label="Allowed values">daily, hourly, never</td>
      <td scope="row" data-label="Notes">Sets the rotation duration for logs.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_LOG_FORMAT</code>_(since v2.4.0)_</td>
      <td scope="row" data-label="Command arg"><code>log-format</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">text</td>
      <td scope="row" data-label="Allowed values">text, json</td>
      <td scope="row" data-label="Notes">Sets the format for logs.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_LOG_OTEL_LEVEL</code><br />_(since v2.4.0)_</td>
      <td scope="row" data-label="Command arg"><code>log-otel-level</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">SURREAL_LOG logging level</td>
      <td scope="row" data-label="Allowed values">none, full, error, warn, info, debug, trace</td>
      <td scope="row" data-label="Notes">Override the logging level for OpenTelemetry</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_LOG_SOCKET</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Command arg"><code>log-socket</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">String to a host:port</td>
      <td scope="row" data-label="Notes">Send logs to the specified host:port</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_LOG_SOCKET_FORMAT</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Command arg"><code>log-socket-format</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">text</td>
      <td scope="row" data-label="Allowed values">text, json</td>
      <td scope="row" data-label="Notes">  Set the format of the logs to the socket.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_LOG_SOCKET_LEVEL</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Command arg"><code>log-socket-level</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">SURREAL_LOG logging level</td>
      <td scope="row" data-label="Allowed values">none, full, error, warn, info, debug, trace</td>
      <td scope="row" data-label="Notes">  Override the logging level for socket logs. Possible values: none, full, error, warn, info, debug, trace</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_NAME</code></td>
      <td scope="row" data-label="Command arg"><code>name</code></td>
      <td scope="row" data-label="Command">`ml export`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">A string</td>
      <td scope="row" data-label="Notes">The name of the model.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_NAMESPACE</code></td>
      <td scope="row" data-label="Command arg"><code>namespace</code></td>
      <td scope="row" data-label="Command">`sql`</td>
      <td scope="row" data-label="Default">main</td>
      <td scope="row" data-label="Allowed values">A string</td>
      <td scope="row" data-label="Notes">The namespace to connect to via the REPL.</td>
    </tr>
<tr>
      <td scope="row" data-label="Env var"><code>SURREAL_NAMESPACE</code></td>
      <td scope="row" data-label="Command arg"><code>namespace</code></td>
      <td scope="row" data-label="Command">`export`, `import`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">A string</td>
      <td scope="row" data-label="Notes">The namespace selected for the import/export operation.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_NO_BANNER</code></td>
      <td scope="row" data-label="Command arg"><code>no-banner</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to hide the startup banner.</td>
    </tr>
<tr>
      <td scope="row" data-label="Env var"><code>SURREAL_NO_DEFAULTS</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Command arg"><code>no-defaults</code></td>
      <td scope="row" data-label="Command"><code>`start`</code></td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to disable default namespace and database creation. Conflicts with SURREAL_DEFAULT_DATABASE and SURREAL_DEFAULT_NAMESPACE, which set a default value for namespace and database for a new instance.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_NO_IDENTIFICATION_HEADERS</code></td>
      <td scope="row" data-label="Command arg"><code>no-identification-headers</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to suppress the server name and version headers.</td>
    </tr>
<tr>
      <td scope="row" data-label="Env var"><code>SURREAL_NODE_MEMBERSHIP_CHECK_INTERVAL</code></td>
      <td scope="row" data-label="Command arg"><code>node-membership-check-interval</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">15s</td>
      <td scope="row" data-label="Allowed values">A duration</td>
      <td scope="row" data-label="Notes">The interval at which to process and archive inactive nodes.</td>
    </tr>
  <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_NODE_MEMBERSHIP_CLEANUP_INTERVAL</code></td>
      <td scope="row" data-label="Command arg"><code>node-membership-cleanup-interval</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">300s</td>
      <td scope="row" data-label="Allowed values">A duration</td>
      <td scope="row" data-label="Notes">The interval at which to process and cleanup archived nodes.</td>
    </tr>
  <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_NODE_MEMBERSHIP_REFRESH_INTERVAL</code></td>
      <td scope="row" data-label="Command arg"><code>node-membership-refresh-interval</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">3s</td>
      <td scope="row" data-label="Allowed values">A duration</td>
      <td scope="row" data-label="Notes">The interval at which to refresh node registration information.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_PASS</code></td>
      <td scope="row" data-label="Command arg"><code>pass</code></td>
      <td scope="row" data-label="Command">`export`, `import`, `sql`, `start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">A string</td>
      <td scope="row" data-label="Notes">Database authentication password to use when connecting.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var">SURREAL_PATH</td>
      <td scope="row" data-label="Command arg"><code>path</code></td>
      <td scope="row" data-label="Command">`fix`, `start`</td>
      <td scope="row" data-label="Default">memory</td>
      <td scope="row" data-label="Allowed values">A string</td>
      <td scope="row" data-label="Notes">Database path used for storing data. As a required argument (albeit with a default), it is not passed in via `--path`.</td>
    </tr>
<tr>
      <td scope="row" data-label="Env var"><code>SURREAL_PLANNER_STRATEGY</code>_(since v3.0.0)_</td>
      <td scope="row" data-label="Command arg"><code>planner-strategy</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">best-effort</td>
      <td scope="row" data-label="Allowed values">best-effort|compute-only|all-read-only</td>
      <td scope="row" data-label="Notes">Which strategy to use with the new query planner introduced in SurrealDB 3.0. The default setting uses the new planner for read-only statements, falling back to the previous compute planner on unimplemented paths. The new planner can be skipped entirely by using compute-only.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_QUERY_TIMEOUT</code></td>
      <td scope="row" data-label="Command arg"><code>query-timeout</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">A duration</td>
      <td scope="row" data-label="Notes">The maximum duration that a set of statements can run for.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_READINESS_HEARTBEAT_MAX_AGE</code>_(since v3.3.0)_</td>
      <td scope="row" data-label="Command arg"><code>readiness-heartbeat-max-age</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">Three times <code>node-membership-refresh-interval</code> (9s)</td>
      <td scope="row" data-label="Allowed values">A duration</td>
      <td scope="row" data-label="Notes">How stale this node's cluster heartbeat may get before <code>/ready</code> reports the node unhealthy. When unset, it is derived as three times <code>node-membership-refresh-interval</code>. Startup warns if the configured value reaches 30s - the interval after which peers archive an unresponsive node and collect its live queries - because a node reported ready after the cluster has written it off keeps taking traffic. The value is not clamped.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_RECLAIM_INTERVAL</code>_(since v3.2.0)_</td>
      <td scope="row" data-label="Command arg"><code>reclaim-interval</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">60s</td>
      <td scope="row" data-label="Allowed values">A duration</td>
      <td scope="row" data-label="Notes">How often the background reaper scans for tombstoned namespace, database, and index data to physically delete after a <code>REMOVE</code> statement.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_RECLAIM_GRACE</code>_(since v3.2.0)_</td>
      <td scope="row" data-label="Command arg"><code>reclaim-grace</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">10m</td>
      <td scope="row" data-label="Allowed values">A duration</td>
      <td scope="row" data-label="Notes">Minimum age a removed namespace, database, or index must reach before its data is reclaimed. The effective grace is the maximum of this value and <code>--tikv-gc-lifetime</code> on TiKV backends.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SLOW_QUERY_LOG_THRESHOLD</code><br />_(since v2.3.8)_</td>
      <td scope="row" data-label="Command arg"><code>slow-log-threshold</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">A duration</td>
      <td scope="row" data-label="Notes">A duration specifying the minimum execution time after which a log is made to indicate a slow query</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SLOW_QUERY_LOG_PARAM_ALLOW</code><br /><code>slow-log-param-allow</code> _(since v2.3.9)_</td>
      <td scope="row" data-label="Command arg"><code>slow-log-param-allow</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">Comma-separated strings</td>
      <td scope="row" data-label="Notes">A comma-separated list of parameter names to include in slow query logs.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SLOW_QUERY_LOG_PARAM_DENY</code>_(since v2.3.9)_</td>
      <td scope="row" data-label="Command arg"><code>slow-log-param-deny</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">Comma-separated strings</td>
      <td scope="row" data-label="Notes">A comma-separated list of parameter names to omit from slow query logs.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_STRICT</code></td>
      <td scope="row" data-label="Command arg"><code>strict</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether strict mode is enabled on this database instance. Ignored since SurrealDB 3.0 after which strictness is defined [per database](/docs/reference/query-language/statements/define/database.md#defining-a-strict-database) instead of instance.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TEMPORARY_DIRECTORY</code></td>
      <td scope="row" data-label="Command arg"><code>temporary-directory</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">String to a directory</td>
      <td scope="row" data-label="Notes">Sets the directory for storing temporary database files</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TOKEN</code></td>
      <td scope="row" data-label="Command arg"><code>token</code></td>
      <td scope="row" data-label="Command">`export`, `import`, `sql`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">A string</td>
      <td scope="row" data-label="Notes">Authentication token in JWT format to use when connecting.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TRANSACTION_TIMEOUT</code></td>
      <td scope="row" data-label="Command arg"><code>transaction-timeout</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">A duration</td>
      <td scope="row" data-label="Notes">The maximum duration that any single transaction can run for.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_UNAUTHENTICATED</code></td>
      <td scope="row" data-label="Command arg"><code>unauthenticated</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to allow unauthenticated access.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_USER</code></td>
      <td scope="row" data-label="Command arg"><code>user</code></td>
      <td scope="row" data-label="Command">`export`, `import`, `sql`, start</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">A string</td>
      <td scope="row" data-label="Notes">Database authentication username to use when connecting.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_VERSION</code></td>
      <td scope="row" data-label="Command arg"><code>version</code></td>
      <td scope="row" data-label="Command">`ml export`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">A string</td>
      <td scope="row" data-label="Notes">The version of the ML model.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_WEB_CRT</code></td>
      <td scope="row" data-label="Command arg"><code>web-crt</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">String to a path</td>
      <td scope="row" data-label="Notes">Path to the certificate file for encrypted client connections.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_WEB_KEY</code></td>
      <td scope="row" data-label="Command arg"><code>web-key</code></td>
      <td scope="row" data-label="Command">`start`</td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">String to a path</td>
      <td scope="row" data-label="Notes">Path to the private key file for encrypted client connections.</td>
    </tr>
  </tbody>
</table>

## Storage backend environment variables

These environment variables are used to configure the storage backend for SurrealDB.

### RocksDB environment variables

Many RocksDB environment variables pertain to memory use. The default configuration results in the following rough estimates of RocksDB memory use on different instances:

| Instance memory size  | Estimate
| ------------- |:-------------:|
| 512 MiB | ~ 80MiB |
| 1 GiB | ~ 80MiB
| 2 GiB | ~ 640MiB
| 4 GiB | ~ 1.25GiB
| 8 GiB | ~ 3.25GiB
| 24 GiB | ~ 12GiB
| 128 GiB | ~ 67GiB

The available environment variables for configuring a RocksDB instance are:

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '50%'}}>Environment variable</th>
      <th scope="col" style={{width: '15%'}}>Default</th>
      <th scope="col" style={{width: '15%'}}>Allowed values</th>
      <th scope="col" style={{width: '30%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_BACKGROUND_FLUSH</code></td>
      <td scope="row" data-label="Default">true</td>
      <td scope="row" data-label="Allowed values">false, true</td>
      <td scope="row" data-label="Notes">Whether to enable background WAL file flushing.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_BACKGROUND_FLUSH_INTERVAL</code></td>
      <td scope="row" data-label="Default">200 (milliseconds)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The interval in milliseconds between background flushes.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_BLOB_COMPRESSION_TYPE</code></td>
      <td scope="row" data-label="Default">snappy</td>
      <td scope="row" data-label="Allowed values">none, snappy, lz4, zstd</td>
      <td scope="row" data-label="Notes">Compression type used for blob files.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_BLOB_FILE_SIZE</code></td>
      <td scope="row" data-label="Default">268,435,456 (256 MiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The target blob file size for RocksDB.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_ENABLE_BLOB_GC</code></td>
      <td scope="row" data-label="Default">true</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to enable blob garbage collection for RocksDB.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_BLOB_GC_AGE_CUTOFF</code></td>
      <td scope="row" data-label="Default">0.5</td>
      <td scope="row" data-label="Allowed values">Float between 0 and 1</td>
      <td scope="row" data-label="Notes">Fractional age cutoff for blob GC.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_BLOB_GC_FORCE_THRESHOLD</code></td>
      <td scope="row" data-label="Default">0.5</td>
      <td scope="row" data-label="Allowed values">Float between 0 and 1</td>
      <td scope="row" data-label="Notes">Discardable ratio threshold to force GC.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_BLOB_COMPACTION_READAHEAD_SIZE</code></td>
      <td scope="row" data-label="Default">0</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Readahead size for blob compaction/GC.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_BLOCK_CACHE_SIZE</code></td>
      <td scope="row" data-label="Default">Dynamically calculated via greater of ((system memory / 2) - 1 GiB) and 16MiB</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">RocksDB <a href="https://github.com/facebook/rocksdb/wiki/memory-usage-in-rocksdb">block cache size</a> in bytes</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_BLOCK_SIZE</code></td>
      <td scope="row" data-label="Default">65,536 (64 KiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The size of each uncompressed data block in bytes.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_COMPACTION_READAHEAD_SIZE</code></td>
      <td scope="row" data-label="Default">4 MiB (systems under 4 GiB), 8 MiB (up to 16 GiB), 16 MiB (others)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The readahead buffer size used during compaction.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_COMPACTION_STYLE</code> </td>
      <td scope="row" data-label="Default">level</td>
      <td scope="row" data-label="Allowed values">level, universal</td>
      <td scope="row" data-label="Notes">Use to specify the database compaction style.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_DELETION_FACTORY_DELETE_COUNT</code></td>
      <td scope="row" data-label="Default">50</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The number of deletions to track in the window.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_DELETION_FACTORY_RATIO</code></td>
      <td scope="row" data-label="Default">0.5</td>
      <td scope="row" data-label="Allowed values">A float</td>
      <td scope="row" data-label="Notes">The ratio of deletions to track in the window.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_DELETION_FACTORY_WINDOW_SIZE</code></td>
      <td scope="row" data-label="Default">1000</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The size of the window used to track deletions.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_ENABLE_BLOB_FILES</code></td>
      <td scope="row" data-label="Default">true</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to enable separate key and value file storage.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_ENABLE_PIPELINED_WRITES</code></td>
      <td scope="row" data-label="Default">true</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to use separate queues for WAL writes and memtable writes.</td>
    </tr>
<tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_GROUPED_COMMIT</code></td>
      <td scope="row" data-label="Default">true</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to enable grouped commit when sync is enabled. When enabled, multiple transaction commits are batched together and flushed to disk with a single fsync operation, improving throughput. When disabled, each transaction is committed and synced individually, which may provide lower latency for single transactions at the cost of reduced throughput under high load. Only used when SURREAL_SYNC_DATA is enabled and SURREAL_ROCKSDB_BACKGROUND_FLUSH is disabled.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_GROUPED_COMMIT_MAX_BATCH_SIZE</code></td>
      <td scope="row" data-label="Default">4096</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum number of transactions in a single grouped commit batch. Used to prevent unbounded memory growth while still allowing large batches for efficiency. Larger batches improve throughput but increase memory usage and commit latency.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_GROUPED_COMMIT_TIMEOUT</code></td>
      <td scope="row" data-label="Default">5ms</td>
      <td scope="row" data-label="Allowed values">A duration</td>
      <td scope="row" data-label="Notes">The maximum wait time in nanosecond before forcing a grouped commit. Used to ensure that transactions do not wait indefinitely when concurrency is low, and to balance between transaction latency and write throughput.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_GROUPED_COMMIT_WAIT_THRESHOLD</code></td>
      <td scope="row" data-label="Default">12</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Threshold for deciding whether to wait for more transactions. If the current batch size is greater or equal to this threshold (and below ROCKSDB_GROUPED_COMMIT_MAX_BATCH_SIZE), then the coordinator will wait up to ROCKSDB_GROUPED_COMMIT_TIMEOUT to collect more transactions. Smaller batches are flushed immediately to preserve low latency.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_FILE_COMPACTION_TRIGGER</code></td>
      <td scope="row" data-label="Default">4</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The number of files needed to trigger level 0 compaction.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_JOBS_COUNT</code></td>
      <td scope="row" data-label="Default">Number of CPUs * 2</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum number of threads to use for flushing and compaction.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_KEEP_LOG_FILE_NUM</code></td>
      <td scope="row" data-label="Default">10</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum number of information log files to keep.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_MAX_CONCURRENT_SUBCOMPACTIONS</code></td>
      <td scope="row" data-label="Default">4</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum number threads which will perform compactions.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_MAX_OPEN_FILES</code></td>
      <td scope="row" data-label="Default">1024</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum number of open files which can be opened by RocksDB.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_MAX_WRITE_BUFFER_NUMBER</code></td>
      <td scope="row" data-label="Default">2 (systems under 4 GiB), 4 (up to 16 GiB), 8 (up to 64 GiB), 32 (others)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum number of write buffers which can be used.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_MIN_BLOB_SIZE</code></td>
      <td scope="row" data-label="Default">4096</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The minimum size in bytes of a value for it to be stored in blob files.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_MIN_WRITE_BUFFER_NUMBER_TO_MERGE</code></td>
      <td scope="row" data-label="Default">2</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The minimum number of write buffers to merge before writing to disk.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_SST_MAX_ALLOWED_SPACE_USAGE</code></td>
      <td scope="row" data-label="Default">0</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum allowed space usage for SST files in bytes. The default of 0 means unlimited and disables space monitoring. When this limit is reached, the datastore enters read-and-deletion-only mode, where only read and delete operations are allowed. This allows gradual space recovery through data deletion.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_STORAGE_LOG_LEVEL</code></td>
      <td scope="row" data-label="Default">warn</td>
      <td scope="row" data-label="Allowed values">none, full, error, warn, info, debug, trace</td>
      <td scope="row" data-label="Notes">The information log level of the RocksDB library.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_TARGET_FILE_SIZE_BASE</code></td>
      <td scope="row" data-label="Default">67,108,864 (64 MiB)</td>
      <td scope="row" data-label="Allowed values">-</td>
      <td scope="row" data-label="Notes">The target file size for compaction in bytes.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_TARGET_FILE_SIZE_MULTIPLIER</code></td>
      <td scope="row" data-label="Default">2</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The target file size multiplier for each compaction level.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_THREAD_COUNT</code></td>
      <td scope="row" data-label="Default">Number of CPUs on machine</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The number of threads to start for flushing and compaction.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_WAL_SIZE_LIMIT</code></td>
      <td scope="row" data-label="Default">0</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The write-ahead-log size limit in MiB.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_ROCKSDB_WRITE_BUFFER_SIZE</code></td>
      <td scope="row" data-label="Default">32 MiB (systems under 1 GiB), 64 MiB (up to 16 GiB), 128 MiB (others)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The amount of data each write buffer can build up in memory.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SYNC_DATA</code></td>
      <td scope="row" data-label="Default">true</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to sync writes to disk before acknowledgement.</td>
    </tr>
  </tbody>
</table>

### SurrealKV environment variables

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '50%'}}>Environment variable</th>
      <th scope="col" style={{width: '15%'}}>Default</th>
      <th scope="col" style={{width: '15%'}}>Allowed values</th>
      <th scope="col" style={{width: '30%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SURREALKV_ENABLE_VLOG</code></td>
      <td scope="row" data-label="Default">true</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to enable value log separation.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SURREALKV_VERSIONED_INDEX</code></td>
      <td scope="row" data-label="Default">false</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to enable versioned index. Only applies when versioning is enabled.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SURREALKV_BLOCK_SIZE</code></td>
      <td scope="row" data-label="Default">65_536 (64 KiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The block size in bytes.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SURREALKV_VLOG_MAX_FILE_SIZE</code></td>
      <td scope="row" data-label="Default">64 MiB (systems under 4 GiB), 128 MiB (up to 16 GiB), 256 MiB (up to 64 GiB), 512 MiB (others)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The readahead buffer size used during compaction.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SURREALKV_VLOG_THRESHOLD</code></td>
      <td scope="row" data-label="Default">4096 (4 KiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The value log threshold in bytes. Values larger than this are stored in the value log.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SURREALKV_BLOCK_CACHE_CAPACITY</code></td>
      <td scope="row" data-label="Default">Dynamically calculated via greater of ((system memory / 2) - 1 GiB) and 16MiB</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum log file size in bytes.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SURREALKV_GROUPED_COMMIT_TIMEOUT</code></td>
      <td scope="row" data-label="Default">5ms</td>
      <td scope="row" data-label="Allowed values">A duration in nanoseconds</td>
      <td scope="row" data-label="Notes">The maximum wait time in nanoseconds before forcing a grouped commit. Ensures that transactions do not wait indefinitely under low concurrency and balances commit latency against write throughput.</td>
    </tr>
<tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SURREALKV_GROUPED_COMMIT_WAIT_THRESHOLD</code></td>
      <td scope="row" data-label="Default">12</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Threshold for deciding whether to wait for more transactions. If the current batch size is greater or equal to this threshold (and below SURREAL_SURREALKV_GROUPED_COMMIT_MAX_BATCH_SIZE), then the coordinator will wait up to SURREAL_SURREALKV_GROUPED_COMMIT_TIMEOUT to collect more transactions. Smaller batches are flushed immediately to preserve low latency.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_SURREALKV_GROUPED_COMMIT_MAX_BATCH_SIZE</code></td>
      <td scope="row" data-label="Default">4096</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The maximum number of transactions in a single grouped commit batch. This prevents unbounded memory growth while still allowing large batches for efficiency. Larger batches improve throughput but increase memory usage and commit latency.</td>
    </tr>
  </tbody>
</table>

### TiKV environment variables

> [!IMPORTANT]
> These variables apply when SurrealDB is started with a `tikv://` endpoint for **local Community experimentation**. They are not the configuration surface for production multi-node HA. Prefer a managed cluster on [SurrealDB Cloud Scale](https://surrealdb.com/pricing/scale) or a self-hosted cluster with [SurrealDB Enterprise](https://surrealdb.com/enterprise). See [Run a multi-node cluster](/docs/running/multi-node.md).

<table>
  <thead>
    <tr>
      <th scope="col" style={{width: '50%'}}>Environment variable</th>
      <th scope="col" style={{width: '15%'}}>Default</th>
      <th scope="col" style={{width: '15%'}}>Allowed values</th>
      <th scope="col" style={{width: '30%'}}>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TIKV_API_VERSION</code></td>
      <td scope="row" data-label="Default">1</td>
      <td scope="row" data-label="Allowed values">A u8</td>
      <td scope="row" data-label="Notes">Which TiKV cluster API version to use.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TIKV_ASYNC_COMMIT</code></td>
      <td scope="row" data-label="Default">true</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to use asynchronous transactions.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TIKV_KEYSPACE</code></td>
      <td scope="row" data-label="Default">none</td>
      <td scope="row" data-label="Allowed values">A string</td>
      <td scope="row" data-label="Notes">A string specifying the keyspace identifier for data isolation.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TIKV_GRPC_MAX_DECODING_MESSAGE_SIZE</code></td>
      <td scope="row" data-label="Default">4,194,304 (4 MiB)</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">Sets the maximum decoding size of a gRPC message.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TIKV_ONE_PHASE_COMMIT</code></td>
      <td scope="row" data-label="Default">true</td>
      <td scope="row" data-label="Allowed values">true, false</td>
      <td scope="row" data-label="Notes">Whether to use one-phase transaction commit.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_TIKV_REQUEST_TIMEOUT</code></td>
      <td scope="row" data-label="Default">10</td>
      <td scope="row" data-label="Allowed values">A usize</td>
      <td scope="row" data-label="Notes">The duration in seconds for requests before they time out.</td>
    </tr>
  </tbody>
</table>

### FoundationDB environment variables

> [!WARNING]
> FoundationDB support is deprecated in SurrealDB `3.0`. Please plan to migrate to a supported storage backend.

<table>
  <thead>
    <tr>
      <th scope="col">Environment variable</th>
      <th scope="col">Default value</th>
      <th scope="col">Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_FOUNDATIONDB_TRANSACTION_MAX_RETRY_DELAY</code></td>
      <td scope="row" data-label="Default">500</td>
      <td scope="row" data-label="Notes">The maximum delay between transaction retries in milliseconds.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_FOUNDATIONDB_TRANSACTION_RETRY_LIMIT</code></td>
      <td scope="row" data-label="Default">5</td>
      <td scope="row" data-label="Notes">The maximum number of times a transaction can be retried.</td>
    </tr>
    <tr>
      <td scope="row" data-label="Env var"><code>SURREAL_FOUNDATIONDB_TRANSACTION_TIMEOUT</code></td>
      <td scope="row" data-label="Default">5000</td>
      <td scope="row" data-label="Notes">The maximum transaction timeout in milliseconds.</td>
    </tr>
  </tbody>
</table>

## SurrealDB Cloud environment variables

Instances on SurrealDB Cloud are not started with a CLI command or environment variables. Instead, they can be set from [SurrealDB Studio](/docs/manage/instances/configure.md) or with [`surrealctl`](/docs/reference/cli/surrealctl/overview.md).
