Overview
Unexpected growth in table storage can increase infrastructure and object storage costs. Pinot stores table data across multiple locations, such as server disk, deep store, and remote object stores used by tiered storage. The Table Storage Usage API reports table size with a breakdown by storage location and highlights mismatches between the expected size and the actual size. This makes it easier to:- Track total storage footprint across disk, deep store, and remote tier storage
- Detect orphaned segments and stale versions
- Identify deep store deleted segments that are still consuming storage
- Debug discrepancies during rebalances, segment replacement, and tiered storage cleanup
Key concepts
Expected size vs Actual size
Pinot reports storage in two ways.Expected size
- Segments that are ONLINE for the table based on Pinot metadata
- Segments found under the deleted segments area in the deep store that are still within the configured retention window
Actual size
- Everything included in the expected size
- Unknown segments found in table directories across server disk, deep store, or remote object storage
- Stale versions of remote segments, where older versions exist alongside the latest
Storage components
Sizes are reported by storage location and component.Server disk
- Local segment directory: segment index directories stored in the table’s local data directory
- Remote segment preload index: local copies of remote tier segments staged for serving
- Remote segment metadata cache: local cached metadata for remote tier segments
Deep store
- Segment compressed data: segment tar.gz objects stored in deep store
- Deleted segments: segments moved to the deleted directory, including:
- within retention
- beyond retention, which is unexpected when cleanup is not running
Remote object store
- Remote segment directory (latest): the latest version of remote tier segments
- Remote segment directory (stale versions): older versions still present
API endpoints
Controller API
The controller endpoint provides a consolidated storage usage view for a table across server instances, deep store, and the remote object store.GET /tables/{tableName}/storageUsage?verbose={true|false}
verbose=falsereturns a summary suitable for dashboards and alertingverbose=truereturns a detailed breakdown intended for investigating discrepancies
Summary response (verbose=false)
Example response
Example response
Summary response (verbose=true)
Verbose adds a breakdown per storage area and lists “unexpected” contributors such as unknown segments and stale versions.
Example response
Example response
Response Schema
The response is hierarchical. To maintain clarity, the data structure is defined in three parts below:- Root Response
- The StorageStats Object (Reused recursively)
- Breakdown Contexts (Specifics for Servers vs. Deep Store)
1. Root Response Fields
| Field | Type | Description |
|---|---|---|
tableName | string | The name of the table being analyzed. |
serverInstances | map | A map of Server Instance IDs (e.g., Server_pinot-server-0) to a StorageStats Object. Represents storage on the actual server nodes. |
deepStore | object | A StorageStats Object representing the storage of the Deep Store (PinotFS/S3). |
remoteS3 | object | A StorageStats Object representing the storage on the Remote S3 for a tier table. |
2. The StorageStats Object
This object structure is used for serverInstances, deepStore, remoteS3, and all nested breakdown objects.
| Field | Type | Description |
|---|---|---|
actualItemsCount | integer | The total count of unique items (segments/files) physically found in the storage location. |
actualSizeInBytes | long | The total physical size (in bytes) of all items found. |
unexpectedItemsCount | integer | The count of items found physically that were not expected (e.g., orphaned segments, temp files). |
unexpectedSizeInBytes | long | The total size (in bytes) of the unexpected items. |
totalStaleVersions | integer | (Tiered tables only) Number of unique versions found that differ from the version calculated via table config and segment CRC. |
breakdown | map | A granular breakdown of storage by sub-directory. See Breakdown Definitions below. Only present when verbose=true |
unexpected | object | Details on why items were flagged as unexpected. Contains keys like unknownItems or beyondRetentionSegments. |
3. Breakdown Definitions
The keys inside thebreakdown object change depending on the context (Server vs. Deep Store).
Context: Server Instance
When inspectingserverInstances, the breakdown contains:
| Key | Description |
|---|---|
localSegmentsDirectory | Stats derived from the physical local disk. This is the segment directories for local segments |
remoteSegmentsPreloadIndex | Stats derived from the physical local disk. This is the preload indexes for remote segments of a tier table if configured |
remoteSegmentsMetadataCache | Stats derived from the physical local disk. This is the metadata cache for remote segments of a tier table if configured |
Context: Deep Store
When inspectingdeepStore, the breakdown contains:
| Key | Description |
|---|---|
onlineSegments | Segments found in <data.dir>/<tableNameWithType>. |
deletedSegments | Segments found in the retention queue: <data.dir>/Deleted_Segments/<rawTableName>. |
upsertSnapshots | Snapshot files for Upsert tables. |
dedupSnapshots | Snapshot files for Dedup tables. |
Context: Remote S3
When inspectingremoteS3, the breakdown contains:
| Key | Description |
|---|---|
segmentDirectory | Segments found under the configured prefix for the tier table. |
Interpreting results
IfunexpectedSizeInBytes is not zero, it could mean:
- Stale remote segment versions
- Segments present in storage but not referenced by Pinot metadata
- Deleted segments beyond retention that still exist in deep store
verbose=true to identify the specific storage component contributing to the difference.
Stale versions
A version is considered stale when it is not the latest expected version for a segment. In remote object storage and local caches for remote tiers, stale versions may remain if cleanup is disabled or delayed.Replication considerations
Replication increases server disk usage because segment directories exist per replica. Deep store and remote object store sizes are reported independently of replica placement.Operational notes
Listing large deep store or S3 prefixes can be slow and may incur additional object store request costs. Useverbose=false for routine monitoring and verbose=true for investigation.
Limitations
During cluster transitions such as rebalances or segment updates,actualSizeInBytes can temporarily exceed expectedSizeInBytes due to overlapping placement and intermediate artifacts.
