Note: APIs and configuration knobs may change in future releases.This is useful when:
- The result set is large and you want to limit memory usage on the client.
- An application UI needs paged navigation through query results (tables, graphs, drilldowns).
- You want simpler application logic for scrolling or pagination instead of manually managing
LIMIT/OFFSETin SQL.
How Pagination Work
A pagination-enabled query follows this lifecycle:- A query is executed once on the cluster.
- The full result set is stored in a temporary result store.
- The first page of results is returned as part of the query response.
- The client then iterates through the results by calling pagination API with:
offset(start row)numRows(page size)
- The client can:
- Move forward or backward in the result set.
- Change page size (
numRows) between calls.
Result Store
The Result Store is responsible for storing query results for pagination-based access. Supported storage options:memoryfile(local filesystem or deep store such as S3/GCS, depending on configuration)s3gcs
Important
memoryis not suitable for production.memoryand local filesystem storage do not work well with more than one broker, because pagination requests may be routed to brokers that do not hold the result set.
Configuration
Result Store Configuration
These configurations control where and how query results are stored.| Configuration | Default | Description |
|---|---|---|
pinot.broker.pagination.protocol | memory | Protocol to use for storage (memory, file, s3, gcs). |
pinot.broker.pagination.temp.dir | /tmp/pinot/query/broker | Local filesystem directory for temporary files. |
pinot.broker.pagination.<protocol> | — | Configuration prefix for options required by the chosen protocol. |
Example: Local File Storage
Example: File Storage Using S3
Storage Cleaner
StarTree supports two cleanup mechanisms:PaginationCleaner (Time-Based Cleanup)
PaginationCleaner is a periodic job that runs on the controller and deletes query results older than a configured TTL. It must be able to call all brokers and therefore needs appropriate authentication configuration.Example:
Miscellaneous Settings
These settings control the default page size and expiry behavior for queries.| Configuration | Default | Description |
|---|---|---|
pinot.broker.query.page.size | 10000 | Page size if numRows is not specified in API calls. |
pinot.broker.pagination.expiration | 1h | Time after which a query result will be deleted. |
controller.cluster.pagination.cleaner.frequencyPeriod | 1h | Frequency of the periodic task that deletes expired results. |
controller.cluster.pagination.cleaner.initialDelay | random | Initial delay before the first run of the cleaner task. |
Quota-Based Storage Cleaner
The Quota-Based Storage Cleaner automatically cleans up temporary query result storage when disk usage exceeds a configured limit. This prevents broker nodes from running out of disk due to:- Long-running queries
- Many concurrent cursor queries
- Large result sets
Cleanup Behavior
- Removes expired results first.
- If storage is still above the target threshold, it cleans additional data based on size.
Note: Configuration for this feature can be updated without restarting the broker.
Example Configuration
Configuration Parameters
| Configuration | Default | Description |
|---|---|---|
pinot.broker.pagination.file.enableStorageCleaner | false | Enables or disables the storage cleaner. |
pinot.broker.pagination.file.maxStoragePerBrokerMB | 1024 | Maximum storage quota for query results per broker (in MB). |
pinot.broker.pagination.file.criticalStorageThresholdPercent | 90 | Cleanup is triggered when usage exceeds this percentage of the max quota. |
pinot.broker.pagination.file.targetStorageThresholdPercent | 60 | Cleaner attempts to reduce storage to this percentage of the max quota. |
User APIs
Submit a Cursor-Enabled Query
EndpointdoPaginate(boolean): Enables cursor-based pagination whentrue.numRows(int, optional): Number of rows to return in the first page.
Iterate Over Results
Endpointoffset(int, required): Start offset of the page.numRows(int, optional): Number of rows in this page. Defaults topinot.broker.query.page.size.
requestId: Unique ID for the queryoffset: First record in current responsenumRows: Number of rows in this pagenextOffsetParams: Pre-filled query parameters for the next page
Iterate Over Results for Local Filesystem
When using the broker’s local filesystem as the result store, the StarTree Cloud Proxy must route calls to the correct broker. Each response includes:brokerHostbrokerPort

