Query results and latency are unchanged, and servers still scan exactly the segments a query needs — a server expands each group it is routed and prunes member segments individually. See Query behavior for more details.
When segment groups help
Segment groups are built for tables with a million files or more, where per-file metadata alone can destabilize the cluster. Consider them from a few hundred thousand files upwards if the table is growing towards that size. Below that, per-file segments are fine: grouping couples member availability (see Caveats) in exchange for a metadata saving you don’t need.What’s supported
Enable segment groups
SetsegmentGroupConfig as a JSON string under the table’s metadata.customConfigs:
A new table is not queryable until its first snapshot completes. Grouped tables are always queried against a pinned, fully ingested snapshot (as are all Iceberg External Tables, via
enableSnapshotConsistency). Until the first sync finishes, queries fail with No active Iceberg snapshots are available for table ….Choosing a group size
Bigger groups save more metadata; smaller groups keep the cluster more granular. The trade-offs, in the order they usually matter:- Metadata saving scales directly with group size: entries drop by roughly the group size.
- Availability blast radius grows with group size. A group is queryable only once every member has loaded, so one unreadable file keeps its whole group out of query results rather than just itself.
- Broker pruning gets coarser. The broker prunes using the group’s aggregate time range — the minimum start and maximum end across its members — so a group spanning a wide time range is harder to prune away. Set
timeBucketto bound the span if your queries filter on time. - Per-group observability — some query statistics are reported per group rather than per member (see Observability), so a larger group makes them coarser.
Enabling on a table that already has data
New files form groups; segments that already exist stay standalone and are never regrouped.Check whether the table is between snapshots
A table is at a snapshot boundary when its last snapshot is fully ingested and no run is in flight. Two read-only calls tell you:GET /tables/{tableNameWithType}/externalTable/checkpoint — the ingestion watermark. Read state:
GET /tables/{tableNameWithType}/externalTable/status — fileOnboardingRun.status must not be RUNNING.
Enabling grouping on a live table
- Confirm the broker prerequisite. The broker configs in Operator reference must be set.
-
Pause the sync schedule. In the Data Portal, use Pause Sync on the table’s details page; through the API, remove
schedulefrom the table’sExternalTableSyncTaskconfig (the Data Portal stashes the old value underschedule.paused). This stops only the automatic cadence — on-demand runs still work while paused, and already-ingested data is untouched. -
Let the in-flight run finish. Poll
…/externalTable/statusuntilfileOnboardingRun.statusis no longerRUNNING. -
Get to a snapshot boundary. Check
…/externalTable/checkpoint. IfstateisIN_PROGRESS, trigger a run and re-check, repeating untilstateisDONE: -
Enable grouping. Add
segmentGroupConfigto the table config as shown above. -
Restore the schedule. Resume Sync in the Data Portal, or put the
schedulevalue back. The next run starts a fresh snapshot with grouping active.
Grouping data that was already ingested
If you leave it alone. Every new file on the Iceberg table forms groups, so the grouped share of the table grows with each run. The ungrouped share drains too, but only as the source table loses files: when an upstream delete or compaction removes a file, its standalone segment stops appearing in new snapshots, and snapshot retention deletes it once the last snapshot referencing it is evicted. On a table whose data ages out or gets compacted upstream, the ungrouped remainder therefore disappears on its own over time. If you need the whole table grouped now, it has to be ingested again as a new table.How groups form
Grouping happens during the normal External Table sync run. Within a run, new member segments are bucketed by partition, tier, and (if configured) time bucket. Any bucket that has accumulated a fullmaxSegmentsPerGroup worth of members is committed as a group. Members left over in a bucket are carried forward to the next page of the same snapshot; whatever remains when the snapshot finalizes is committed as one smaller group per bucket. No member ever becomes a standalone segment.
Group names are content-addressed (group_<table>_<minStart>_<maxEnd>_<hash>), so a group whose file set changes in a later snapshot appears under a new name and the old one is retired by snapshot retention.
Caveats
A group is available only as a whole
Servers load a group’s members together, and the group goes ONLINE only when all of them succeed. If one member fails to load, the members already loaded in that attempt are unloaded and the group goes into ERROR. Recovery is to fix the underlying file or segment and reset the group; reset works at group granularity, not per member.Query behavior
Your queries don’t change: same SQL, same schema, same results. What changes underneath is where pruning happens. Pruning happens at two levels. The broker prunes whole groups using their aggregate metadata, which is coarser than per-file pruning. The server then expands the groups it was routed and prunes member segments individually before scanning, so a query still only reads the files it needs.Observability
Grouping changes what shows up where. The control plane reports groups; servers report members.
External Table sync status, ingestion lag, and the file-listing endpoints are unaffected — see Observability.
Turn it off
SettingsegmentGroupConfig.enabled back to false is accepted at any time, and is harmless on a table that has not formed any groups yet — it simply reverts the table to ordinary per-file segments.
On a table that already has groups, the flip is not a no-op. The flag does not un-group anything; instead, the next sync run re-ingests the whole table:
- The ungrouped sync path recognizes already-ingested files by their standalone segment names in the ideal state. Member segments are never in the ideal state, so every file that was inside a group is treated as new and gets a fresh standalone segment generated and uploaded. On a million-file table that is a full re-ingest, paged across many runs.
- Queries stay pinned to the last completed (grouped) snapshot while this happens, so results remain correct and complete. Once the first ungrouped snapshot completes, the broker routes to the new standalone segments only, and snapshot retention deletes the old groups after their last referencing snapshot is evicted.

