> ## Documentation Index
> Fetch the complete documentation index at: https://docs.streamnative.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Dynamic Configuration Guide

StreamNative Ursa supports **dynamic configuration** at the **cluster**, **namespace**, and **topic** levels. This guide explains the supported configuration keys, the cluster-name prefix requirement, and how to apply them with `pulsar-admin`.

## Configuration Key Format

All dynamic configuration keys **must be prefixed with the cluster name**.

| Scope     | Key format                     | Example (cluster name `private-cloud`) |
| --------- | ------------------------------ | -------------------------------------- |
| Cluster   | `<cluster-name>.cluster.<key>` | `private-cloud.cluster.sdt.enabled`    |
| Namespace | `<cluster-name>.<key>`         | `private-cloud.sdt.enabled`            |
| Topic     | `<cluster-name>.<key>`         | `private-cloud.sdt.enabled`            |

### Finding the Cluster Name

The cluster name is the value of the `clusterName` property in the Pulsar broker configuration (`conf/broker.conf`):

```properties theme={null}
# conf/broker.conf
clusterName=private-cloud
```

You can also retrieve it from a running broker pod:

```bash theme={null}
kubectl exec -n pulsar <broker-pod> -- grep '^clusterName' /pulsar/conf/broker.conf
```

Use this exact value as the `<cluster-name>` prefix in all the keys below.

### Backward Compatibility

For existing clusters that do not use the cluster-name prefix, disable the prefix check by setting the following property in the broker configuration:

```
checkClusterName=false
```

## Override Priority

Settings at a more specific level override broader settings:

```
Topic properties
    ↓ (overrides)
Namespace properties
    ↓ (overrides)
Cluster properties (sn/system)
```

## Supported Dynamic Configuration Keys

### Cluster-Level Keys

Cluster-level keys are applied via the `sn/system` namespace.

| Key                                                                       | Description                                    |
| ------------------------------------------------------------------------- | ---------------------------------------------- |
| `<cluster-name>.cluster.sdt.enabled`                                      | Enable External Table (SDT) for the cluster    |
| `<cluster-name>.cluster.sbt.enabled`                                      | Enable Internal Table (SBT) -- **Coming Soon** |
| `<cluster-name>.cluster.sdt.catalog.name`                                 | Default catalog name for SDT                   |
| `<cluster-name>.cluster.tail.compact.data.visibility.interval.in.seconds` | Data visibility delay (seconds)                |

### Namespace-Level and Topic-Level Keys

These keys can be applied at either the namespace or topic level. Topic-level values override namespace-level values.

#### Enablement and Catalog Selection

| Key                                                               | Description                                    |
| ----------------------------------------------------------------- | ---------------------------------------------- |
| `<cluster-name>.sdt.enabled`                                      | Enable SDT for the namespace or topic          |
| `<cluster-name>.sbt.enabled`                                      | Enable SBT -- **Coming Soon**                  |
| `<cluster-name>.sdt.catalog.name`                                 | Catalog name to use for the namespace or topic |
| `<cluster-name>.tail.compact.data.visibility.interval.in.seconds` | Data visibility delay (seconds)                |

> Compaction task publishing is enabled when either `sdt.enabled` or `sbt.enabled` is `true`.

#### Topic-Level Feature Configuration

These keys configure feature behavior for individual topics:

| Key                                             | Scope                       | Description                                                                                                                  |
| ----------------------------------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `<cluster-name>.partition.key`                  | Topic only                  | JSON-encoded partition specification for Iceberg tables. Setting this at cluster or namespace level has no effect.           |
| `<cluster-name>.upsert.mode.enabled`            | Cluster / Namespace / Topic | Enable upsert mode (`true` / `false`)                                                                                        |
| `<cluster-name>.identifier.fields`              | Topic only                  | Comma-separated list of identifier fields used as the primary key. Setting this at cluster or namespace level has no effect. |
| `<cluster-name>.iceberg.write-props.<property>` | Namespace / Topic           | Iceberg [write properties](https://iceberg.apache.org/docs/nightly/configuration/#write-properties)                          |
| `<cluster-name>.iceberg.table-props.<property>` | Namespace / Topic           | Iceberg [table properties](https://iceberg.apache.org/docs/nightly/configuration/#table-behavior-properties)                 |

For the detailed semantics of each feature key, see:

* [Partition Key](/private-cloud/v2/configure-private-cloud/private-preview/ursa-lakehouse/features/iceberg-partition-key)
* [Upsert](/private-cloud/v2/configure-private-cloud/private-preview/ursa-lakehouse/features/iceberg-upsert)

## Apply Dynamic Configuration

The examples below assume a cluster named `private-cloud`.

### Cluster Level

Cluster-level properties are stored in the `sn/system` namespace.

```bash theme={null}
bin/pulsar-admin namespaces set-properties \
  -p private-cloud.cluster.sdt.enabled=true \
  sn/system
```

### Namespace Level

```bash theme={null}
bin/pulsar-admin namespaces set-properties \
  -p private-cloud.sdt.enabled=true \
  <tenant>/<namespace>
```

### Topic Level

```bash theme={null}
bin/pulsar-admin topics update-properties \
  -p private-cloud.sdt.enabled=true \
  persistent://<tenant>/<namespace>/<topic>
```

### Apply Multiple Keys at Once

You can specify `-p key=value` multiple times in a single command:

```bash theme={null}
bin/pulsar-admin topics update-properties \
  -p private-cloud.sdt.enabled=true \
  -p private-cloud.sdt.catalog.name=polaris-prod \
  -p private-cloud.upsertModeEnabled=true \
  -p private-cloud.identifierFields=userId,email \
  persistent://public/default/users
```

## Extending Valid Dynamic Configuration Keys

By default, only the keys listed above are accepted. To add additional keys, set the following environment variable when starting the Pulsar broker:

```bash theme={null}
LAKEHOUSE_DYNAMIC_EXTRA_VALID_KEYS_IN_CONF_FILE=<key1>,<key2>,<key3>
```

Example:

```bash theme={null}
LAKEHOUSE_DYNAMIC_EXTRA_VALID_KEYS_IN_CONF_FILE=clusterSdtEnabled,clusterSbtEnabled,clusterSdtCatalogName
```

## Next Steps

* [Enable Lakehouse Integration](/private-cloud/v2/configure-private-cloud/private-preview/ursa-lakehouse/enable-lakehouse-integration) -- Enable SDT/SBT at cluster/namespace/topic level
* Feature configuration:
  * [Schema Evolution](/private-cloud/v2/configure-private-cloud/private-preview/ursa-lakehouse/features/schema-evolution)
  * [Variant Type](/private-cloud/v2/configure-private-cloud/private-preview/ursa-lakehouse/features/variant-type)
  * [Partition Key](/private-cloud/v2/configure-private-cloud/private-preview/ursa-lakehouse/features/iceberg-partition-key)
  * [Upsert](/private-cloud/v2/configure-private-cloud/private-preview/ursa-lakehouse/features/iceberg-upsert)
  * [Persist Key](/private-cloud/v2/configure-private-cloud/private-preview/ursa-lakehouse/features/persist-key)
  * [Persist Extra Metadata](/private-cloud/v2/configure-private-cloud/private-preview/ursa-lakehouse/features/persist-extra-metadata)
