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

# Segment Reload Dry Run

> Preview segment reload index changes before running a table reload.

Segment reload dry run previews what a table reload would change before you run the real reload. It samples table segments on the servers that host them, loads temporary segment copies with the proposed indexing config and schema, then returns the estimated index additions/removals, preprocessing time, size change, and any per-segment errors.

<Info>
  Dry run does not mutate the live segment directories. It creates temporary copies for sampled local segments and deletes them after the check.
</Info>

## When to Use

Use reload dry run before:

* Adding, removing, or changing indexes on a large table.
* Reloading segments after a schema or table-index config change.
* Estimating segment size growth from new index settings.
* Validating whether sampled segments can be reloaded successfully before triggering a full reload.
* Comparing index changes across old, latest, or random segment samples.

For task-level planning such as Segment Backfill or Segment Purge, use the task dry-run APIs for those task types instead.

## Endpoint

```http theme={null}
POST /tables/{tableNameWithType}/reload/dryRun
Content-Type: application/json
```

Path parameter:

| Parameter           | Description                                                                 |
| ------------------- | --------------------------------------------------------------------------- |
| `tableNameWithType` | Table name with type suffix, such as `orders_OFFLINE` or `events_REALTIME`. |

The controller:

1. Resolves the table config and schema from ZooKeeper.
2. Applies only index-loading-related fields from the request's proposed `tableConfig`.
3. Sends the enriched request to servers hosting the table.
4. Aggregates server responses into one controller-level response.

If segment preprocessing is disabled for the table, the response is empty because no index changes can be previewed.

## Request Body

| Field            | Required | Default              | Description                                                                                                              |
| ---------------- | -------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `tableConfig`    | No       | Current table config | Proposed table config to evaluate. The controller uses only relevant indexing and field-config changes from this object. |
| `schema`         | No       | Current schema       | Proposed schema to evaluate.                                                                                             |
| `sampleStrategy` | No       | `RANDOM`             | Segment sampling strategy. Supported values: `RANDOM`, `OLDEST`, `LATEST`. Ignored when `targetSegments` is non-empty.   |
| `sampleCount`    | No       | `5`                  | Number of segments to sample per server. Maximum is `10`.                                                                |
| `targetSegments` | No       | `[]`                 | Explicit segment names to dry run. When set, sampling strategy and count are ignored.                                    |
| `timeoutMs`      | No       | `10000`              | Timeout in milliseconds for sampled segment dry-run work.                                                                |

## Example: Preview an Inverted Index

This request previews adding an inverted index to the `status` column and a bloom filter to `customerId`.

```bash theme={null}
curl -sS -X POST "https://<controller-host>:9000/tables/orders_OFFLINE/reload/dryRun" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "sampleStrategy": "RANDOM",
    "sampleCount": 5,
    "timeoutMs": 30000,
    "tableConfig": {
      "fieldConfigList": [
        {
          "name": "status",
          "encodingType": "DICTIONARY",
          "indexTypes": ["INVERTED"]
        },
        {
          "name": "customerId",
          "encodingType": "DICTIONARY",
          "indexTypes": ["BLOOM"]
        }
      ]
    }
  }' | jq
```

Example response:

```json theme={null}
{
  "tableNameWithType": "orders_OFFLINE",
  "sampledSegments": [
    "orders_2026_01_01_0",
    "orders_2026_01_01_1"
  ],
  "avgTimeMsPerSegment": 842,
  "netColumnIndexChanged": {
    "status": {
      "added": ["inverted"],
      "removed": []
    },
    "customerId": {
      "added": ["bloom"],
      "removed": []
    }
  },
  "avgSizeChangeInBytes": 1843200,
  "totalSegmentsNeedReload": 214,
  "numExceptions": 0,
  "serverResults": {
    "Server_10.0.2.18_8098": {
      "totalSegmentsNeedReload": 107,
      "sampledSegmentResults": [
        {
          "name": "orders_2026_01_01_0",
          "timeMsPreprocess": 806,
          "sizeChangeInBytes": 1748992,
          "columnIndexChanged": {
            "status": {
              "added": ["inverted"],
              "removed": []
            }
          },
          "exception": null
        }
      ]
    }
  }
}
```

## Example: Target Specific Segments

Use `targetSegments` when you want to dry run the exact segments that failed a previous reload or segments representative of a known time range.

```bash theme={null}
curl -sS -X POST "https://<controller-host>:9000/tables/orders_OFFLINE/reload/dryRun" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "targetSegments": [
      "orders_2026_02_01_0",
      "orders_2026_02_01_1"
    ],
    "timeoutMs": 60000,
    "tableConfig": {
      "fieldConfigList": [
        {
          "name": "status",
          "encodingType": "DICTIONARY",
          "indexTypes": ["INVERTED"]
        }
      ]
    }
  }'
```

Each server intersects the requested list with its locally hosted segments. A server that does not host any requested segment returns an empty per-server response.

## Sampling Strategies

| Strategy | Behavior                                                                                                                         |
| -------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `RANDOM` | Reservoir-samples local segments on each server. Use this for broad estimates.                                                   |
| `OLDEST` | Samples the oldest local segments by segment creation time. Use this when old segments may have outdated formats or configs.     |
| `LATEST` | Samples the newest local segments by segment creation time. Use this when recent ingestion changes might affect reload behavior. |

Remote segments that are not locally materialized can be counted as needing reload but are excluded from sample execution. The dry-run response can therefore show `totalSegmentsNeedReload` greater than `sampledSegments.length`.

## Response Fields

| Field                     | Description                                                                                  |
| ------------------------- | -------------------------------------------------------------------------------------------- |
| `tableNameWithType`       | Resolved table name with type.                                                               |
| `sampledSegments`         | Flat list of segments that completed dry run successfully.                                   |
| `avgTimeMsPerSegment`     | Average preprocessing/load time across successful sampled segments.                          |
| `netColumnIndexChanged`   | Union of per-column index additions and removals across successful samples.                  |
| `avgSizeChangeInBytes`    | Average size delta for successful sampled segments. Positive means segment directories grew. |
| `totalSegmentsNeedReload` | Sum of server-reported segments that need reload.                                            |
| `numExceptions`           | Total per-server and per-segment exception count.                                            |
| `serverResults`           | Per-server detail, keyed by server instance ID.                                              |

Per-segment result fields:

| Field                | Description                                                                          |
| -------------------- | ------------------------------------------------------------------------------------ |
| `name`               | Segment name.                                                                        |
| `timeMsPreprocess`   | Time spent preprocessing/loading the temporary copy. Omitted when the segment fails. |
| `sizeChangeInBytes`  | Size delta for the temporary segment directory. Omitted when the segment fails.      |
| `columnIndexChanged` | Per-column index additions/removals for that segment.                                |
| `exception`          | `null` on success, otherwise a segment-level failure message.                        |

## Operational Notes

* Dry run uses temporary segment directories and deletes them after the request.
* Dry-run work is isolated from the real reload executor so it does not consume real reload worker threads.
* `sampleCount` is capped at `10` to prevent expensive accidental scans.
* `timeoutMs` applies to sampled segment dry-run work. Timed-out segments appear with an exception such as `Dry-run timed out`.
* The controller always starts from the ZooKeeper table config and applies proposed indexing and field-config changes from the request.
* Tier backend settings are adjusted so dry-run loading uses local temporary copies rather than writing to remote tier storage.

## Interpreting Results

Use `netColumnIndexChanged` to confirm the reload would perform the expected index transition. For example:

```json theme={null}
{
  "status": {
    "added": ["inverted"],
    "removed": []
  },
  "message": {
    "added": ["text"],
    "removed": ["fst"]
  }
}
```

Use `avgSizeChangeInBytes` as a sample-based estimate, not an exact whole-table storage forecast. Multiply it by the number of segments that need reload to estimate rough footprint change, then validate with a larger or targeted sample if the result is close to your storage budget.

If `numExceptions` is non-zero, inspect `serverResults` before triggering a full reload. Common failures include invalid index config, incompatible schema changes, segment format issues, or request timeout.

## Troubleshooting

| Symptom                                                         | Cause                                                                                           | Fix                                                                     |
| --------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `Sample count cannot exceed 10`                                 | `sampleCount` is above the server-side limit.                                                   | Reduce `sampleCount` or use `targetSegments`.                           |
| Empty response                                                  | Table preprocessing is disabled or no hosted segments need reload.                              | Check `skipSegmentPreprocess`, table config, and segment reload status. |
| `Dry-run timed out`                                             | A sampled segment did not finish before `timeoutMs`.                                            | Increase `timeoutMs`, reduce sample size, or target fewer segments.     |
| Segment appears in `totalSegmentsNeedReload` but not in samples | Segment is remote-only on that server or was not selected by sampling.                          | Use targeted segments hosted locally or run a larger sample.            |
| Proposed index change does not appear                           | Request table config did not include the relevant `fieldConfigList` or `indexingConfig` change. | Include the proposed field/index config in the request body.            |
