# Advanced (config.yaml-only) (/configure/reference/advanced)



These are advanced, low-level knobs. The **message-broker engine** (`broker.*`), **runtime
tuning** (`tuning.*`), and **standalone clustering** (`cluster.*`) have **no Helm/CRD path**
— they are Docker / `config.yaml`-only, so their Helm/CRD column is `—` (per the
[reference legend](/configure/reference)). On Kubernetes the operator owns those
concerns. **Routing** is the exception: three of its fields (`data`, `url`, `autoReload`)
map to `spec.routing.*` on the CRD.

## Message-broker engine [#message-broker-engine]

The embedded message-broker engine's internal limits and buffers, configured through the
`broker.*` block. These are Docker / `config.yaml`-only; there is **no Helm/CRD path** (the
operator owns the engine on Kubernetes). Most fields bind to a `BROKER_*` env var — but the
two auto-assigned ports (`port`, `monitoringPort`) have **no env var** and are file-only.

| Setting            | Type           | Default                   | Valid values | Docker (config.yaml key · env var)                           | Helm/CRD path | Notes                                                                                                                                              |
| ------------------ | -------------- | ------------------------- | ------------ | ------------------------------------------------------------ | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Port               | int            | auto (free port)          | port number  | `broker.port&#x60; · &#x2A;(no env var)*                     | —             | Ephemeral — a free port is picked at every startup (`getFreePort()`). Not meant to be pinned; **no `BROKER_PORT` env var exists**. Not validated.  |
| Max payload        | int (bytes)    | `1048576000` (\~1000 MiB) | ≥ 0          | `broker.maxpayload` · `BROKER_MAX_PAYLOAD`                   | —             | Max message payload in **bytes**. Cast to `int32` when applied, so the effective ceiling is 2,147,483,647 bytes (\~2 GiB); larger values overflow. |
| Write deadline     | int (ms)       | `2000`                    | ≥ 0          | `broker.writedeadline` · `BROKER_WRITE_DEADLINE`             | —             | Per-write deadline in **milliseconds**.                                                                                                            |
| Max connections    | int            | `0` (unlimited)           | ≥ 0          | `broker.maxconn` · `BROKER_MAX_CONN`                         | —             | `0` = unlimited.                                                                                                                                   |
| Monitoring port    | int            | auto (free port)          | 1–65535      | `broker.monitoringport&#x60; · &#x2A;(no env var)*           | —             | Ephemeral — picked at every startup. &#x2A;*No `BROKER_MONITORING_PORT` env var exists.** This is the only broker field validated as a port.       |
| Write buffer size  | int (**MB**)   | `2` (→ 2 MB)              | ≥ 0          | `broker.writebuffersize` · `BROKER_WRITE_BUFFER_SIZE`        | —             | Value is in **megabytes** — the config value is multiplied by 1024×1024 (`broker.go:52`). `2` means 2 MB, **not** 2 bytes.                         |
| Read buffer size   | int (**MB**)   | `10` (→ 10 MB)            | ≥ 0          | `broker.readbuffersize` · `BROKER_READ_BUFFER_SIZE`          | —             | Value is in **megabytes** (×1024×1024, `broker.go:53`). Read-ahead buffer. `10` = 10 MB.                                                           |
| Disk sync (s)      | int            | `5`                       | ≥ 0          | `broker.disksyncseconds` · `BROKER_DISK_SYNC_SECONDS`        | —             | Disk flush interval in **seconds**. Lowered from 60 s → 5 s to shrink the data-loss window.                                                        |
| Slice max messages | int            | `0` (unlimited)           | ≥ 0          | `broker.slicemaxmessages` · `BROKER_SLICE_MAX_MESSAGES`      | —             | `0` = no message-count limit per file slice.                                                                                                       |
| Slice max bytes    | int64 (**MB**) | `64` (→ 64 MB)            | ≥ 0          | `broker.slicemaxbytes` · `BROKER_SLICE_MAX_BYTES`            | —             | Per-slice ceiling in **megabytes** (×1024×1024, `broker.go:56`). `64` = 64 MB.                                                                     |
| Slice max age (s)  | int            | `0` (no rollover)         | ≥ 0          | `broker.slicemaxageseconds` · `BROKER_SLICE_MAX_AGE_SECONDS` | —             | `0` = no age-based slice rollover. Value in **seconds**.                                                                                           |
| Parallel recovery  | int            | `4`                       | **≥ 1**      | `broker.parallelrecovery` · `BROKER_PARALLEL_RECOVERY`       | —             | Recovery worker count. Must be **≥ 1** (`0` or negative is rejected).                                                                              |

<Callout type="warn">
  `broker.writeBufferSize`, `broker.readBufferSize`, and `broker.sliceMaxBytes` are expressed
  in **megabytes**, not bytes — the raw config value is multiplied by 1024×1024 internally. Set
  `readBufferSize: 10` for a 10 MB buffer. `broker.maxPayload`, by contrast, is in **bytes**.
</Callout>

## Runtime tuning [#runtime-tuning]

Optional Go-runtime tuning through the `tuning.*&#x60; block. Every zero value means
"auto-detect from the environment." **`TuningConfig` is the one config domain with no env-var
bindings at all** — there are **no `TUNING_*` environment variables** (verified: `tuning.go`'s
`defaultTuningConfig()` makes no `bindViperEnv` call). These keys are therefore **only settable
through a mounted `config.yaml`/TOML file**. There is no Helm/CRD path. For the three fields
that wrap standard Go knobs, the Go runtime independently honors the native `GOGC`,
`GOMEMLIMIT`, and `GOMAXPROCS` env vars.

| Setting               | Type | Default    | Valid values | Docker (config.yaml key · env var)                   | Helm/CRD path | Notes                                                                                                |
| --------------------- | ---- | ---------- | ------------ | ---------------------------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------- |
| GC percent            | int  | `0` (auto) | ≥ 0          | `tuning.gc_percent&#x60; · &#x2A;(no env var)*       | —             | Config-file-only. Wraps Go GC frequency; use the native `GOGC` env var instead for env-based tuning. |
| Memory limit (MB)     | int  | `0` (auto) | ≥ 0          | `tuning.memory_limit_mb&#x60; · &#x2A;(no env var)*  | —             | Config-file-only. Wraps `GOMEMLIMIT`; use the native `GOMEMLIMIT` env var for env-based tuning.      |
| Max procs             | int  | `0` (auto) | ≥ 0          | `tuning.max_procs&#x60; · &#x2A;(no env var)*        | —             | Config-file-only. Wraps `GOMAXPROCS`; use the native `GOMAXPROCS` env var for env-based tuning.      |
| Pipe init buffer (KB) | int  | `0` (auto) | ≥ 0          | `tuning.pipe_init_buf_kb&#x60; · &#x2A;(no env var)* | —             | Config-file-only. Internal memory-pipe initial buffer size.                                          |
| Pipe max buffer (KB)  | int  | `0` (auto) | ≥ 0          | `tuning.pipe_max_buf_kb&#x60; · &#x2A;(no env var)*  | —             | Config-file-only. Internal memory-pipe maximum buffer size.                                          |
| Allow TLS SHA-1       | bool | `false`    | true / false | `tuning.tls_allow_sha1&#x60; · &#x2A;(no env var)*   | —             | Config-file-only. Permits SHA-1 in TLS cipher suites (legacy interop).                               |

<Callout type="info">
  `tuning.*` keys use `snake_case` in `config.yaml` (they carry explicit `mapstructure` tags —
  `gc_percent`, `memory_limit_mb`, etc.), unlike the dotted-camel keys elsewhere. Because there
  are **no `TUNING_*` env vars**, a K8s CRD/Helm chart cannot set these today without a custom
  mounted config file — prefer the native `GOGC` / `GOMEMLIMIT` / `GOMAXPROCS` container env
  vars for GC/memory/CPU tuning.
</Callout>

## Standalone clustering [#standalone-clustering]

Manual standalone clustering for Docker, configured through the `cluster.*&#x60; block. Uses the
server's standard &#x2A;*`enable: true/false`** toggle. This is Docker / `config.yaml`-only (env
`CLUSTER_*`) — there is **no Helm/CRD path**. On Kubernetes, high availability is
`spec.replicas` (operator-managed clustering), not `cluster.*`; the operator injects the
`CLUSTER_*` env vars into the StatefulSet pod template itself — see
[Deployment & High Availability](/configure/reference/deployment).

| Setting        | Type   | Default  | Valid values | Docker (config.yaml key · env var)   | Helm/CRD path | Notes                                                                                              |
| -------------- | ------ | -------- | ------------ | ------------------------------------ | ------------- | -------------------------------------------------------------------------------------------------- |
| Enable         | bool   | `false`  | true / false | `cluster.enable` · `CLUSTER_ENABLE`  | —             | Master toggle. When `false`, all other `cluster.*` fields are ignored (validation short-circuits). |
| Cluster name   | string | `kubemq` | name string  | `cluster.name` · `CLUSTER_NAME`      | —             | Shared cluster identifier across peers.                                                            |
| Cluster port   | int    | `5228`   | 1–65535      | `cluster.port` · `CLUSTER_PORT`      | —             | Peer-to-peer cluster port. Validated only when `enable: true`.                                     |
| Cluster routes | string | `""`     | route list   | `cluster.routes` · `CLUSTER_ROUTES`  | —             | Addresses of peer nodes to connect to.                                                             |
| Is seed        | bool   | `false`  | true / false | `cluster.isseed` · `CLUSTER_IS_SEED` | —             | Whether this node is a seed node. Struct field is `IsSeed`; config.yaml key is `cluster.isseed`.   |

<Callout type="info">
  The `next` storage engine uses an additional replication membership plane managed by Dragonboat. Its dedicated `Cluster.Replication.*` configuration fields and `POD_NAME`→`ReplicaID` auto-derivation are documented in the [Storage Engines](/configure/reference/storage-engines) reference page.
</Callout>

## Routing [#routing]

Channel-routing rules, configured through the `routing.*&#x60; block. The server uses the standard
&#x2A;*`enable: true/false`** toggle. On the CRD, routing has **no explicit toggle** — the operator
auto-emits `ROUTING_ENABLE=true` whenever `spec.routing.data` **or** `spec.routing.url` is set.
Three fields map to `spec.routing.*`; `enable` and `filePath` are Docker-only (`—`).

| Setting          | Type   | Default   | Valid values         | Docker (config.yaml key · env var)           | Helm/CRD path             | Notes                                                                                                                                                                                     |
| ---------------- | ------ | --------- | -------------------- | -------------------------------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Enable           | bool   | `false`   | true / false         | `routing.enable` · `ROUTING_ENABLE`          | —                         | Master toggle (server side). On the CRD it is implicit — set automatically when `data` or `url` is provided. When `false`, the rest of the block is ignored.                              |
| Routing data     | string | `""`      | inline routing rules | `routing.data` · `ROUTING_DATA`              | `spec.routing.data`       | Inline routing table. Consumed **raw** (not base64-decoded), so the operator emits it as a plain ConfigMap variable. Takes precedence over `filePath` and `url`.                          |
| Routing URL      | string | `""`      | URL                  | `routing.url` · `ROUTING_URL`                | `spec.routing.url`        | Fetch the routing table from a URL. Validated as a URL when set. Struct field is `URL`; config.yaml key is `routing.url`. Emitted raw.                                                    |
| Auto-reload (ms) | int    | `0` (off) | ≥ 0                  | `routing.autoreload` · `ROUTING_AUTO_RELOAD` | `spec.routing.autoReload` | Reload interval in **milliseconds**. `0` disables periodic reload. CRD field is `int32`, `omitempty` — the operator only emits `ROUTING_AUTO_RELOAD` when non-zero (no CRD-side default). |
| Routing file     | string | `""`      | file path            | `routing.filepath` · `ROUTING_FILE_PATH`     | —                         | Load rules from a file path. Docker / config.yaml-only — **not** exposed on the CRD (superseded by inline `data`). Validated as a filename when set.                                      |

<Callout type="info">
  When routing is enabled you must provide **exactly one** source: `data`, `filePath`, or `url`
  (enabling routing with none set is a configuration error). Precedence when more than one is
  present: `data` → `filePath` → `url`. `autoReload` must be ≥ 0.
</Callout>

## Example [#example]

Set a message-broker buffer. On Docker this is a `config.yaml` key (in **MB**) or a `BROKER_*`
env var; on Kubernetes the broker engine has **no Helm/CRD path**, so the operator owns it.
This is a single-setting snippet — see the [Docker guide](/configure/docker) for complete,
runnable configurations.

<Tabs items="[&#x22;Docker&#x22;, &#x22;Helm&#x22;]">
  <Tab value="Docker">
    ```yaml title="config.yaml"
    broker:
      readBufferSize: 10   # megabytes → 10 MB
    ```
  </Tab>

  <Tab value="Helm">
    ```yaml title="values.yaml"
    # Not available on Helm/CRD — the message-broker engine is config.yaml-only.
    # On Kubernetes the operator manages the broker engine.
    ```
  </Tab>
</Tabs>

For the full Docker delivery methods (env vars, mounted `config.yaml`, the `CONFIG`
variable) see the [Docker guide](/configure/docker).
