Minn Fong
06/04/2026, 1:55 PMRocky
06/04/2026, 1:56 PMi4i.4xlarge Sufficient for the PK Index?
Your memory calculation for a fully in-memory index is likely on the edge:
* Memory Formula: (PK_size + 9) _ row_count _ 1.5.
* Your Estimate: (46 + 9) _ 5.85B _ 1.5 ≈ 482 GB of RAM.
* Cluster RAM: 6 nodes × 128 GiB = 768 GiB.
While 482 GB fits within 768 GB, StarRocks generally recommends that the Primary Key index consumes no more than 50-60% of the available BE/CN process memory to leave room for query execution, compaction, and loading. At ~63% utilization, you might experience OOM (Out of Memory) issues during heavy query/load concurrency.
Recommendation: Use Persistent Index (enable_persistent_index = true).
* Starting in v3.1.4 (Local) and v3.3.2 (Cloud Native), Shared-data supports persistent PK indexes.
* This offloads the bulk of the 482 GB index to your NVMe drives, using only a small fraction of RAM for the L0 (hottest) part of the index. This makes your 6-node cluster "plenty" and very stable.
3. Cache Thrashing and NVMe Sizing
Your reasoning regarding the cache is correct. Given that your active data (10TB) is less than 50% of your total NVMe cache (22.5TB):
* Thrashing: This should be a non-issue. Since the entire 24-hour working set fits in the cache, StarRocks will essentially perform at the speed of a local SSD-based Shared-nothing cluster after the initial "warm-up" (first read/load).
* Query Patterns: Because your entire dataset lives in the cache, query patterns (random vs. sequential) will benefit from NVMe speeds. You won't suffer the "cold read" latency of object storage unless you query beyond the 24-hour window.
* Configuration: Ensure you set datacache.enable = true and monitor the DataCache metrics in your Query Profiles to verify 100% hit rates.
Summary Checklist
* Architecture: Shared-data.
* Index Type: Set "enable_persistent_index" = "true" and "persistent_index_type" = "CLOUD_NATIVE" (if on v3.3.2+).
* Bucketing: With 10TB and 6 nodes, aim for a tablet size of roughly 1-5GB to ensure even distribution across your 16 vCPUs per node.
* Persistence: Since you are on i4i instances (AWS Nitro SSDs), the persistent index performance will be excellent.
References
• best_practices/primarykey_table.md
• table_design/table_types/primary_key_table.mdMinn Fong
06/04/2026, 1:59 PMRocky
06/04/2026, 1:59 PMdatacache.partition_duration.
* Setting: If you set this to 1 day, StarRocks will only cache data belonging to partitions created within the last 24 hours.
* Behavior: Queries against older data (Days 2–4) will be served directly from S3/object storage without occupying any NVMe cache space, effectively "pinning" your cache to the most recent day.
3. Session Variables to Bypass Cache
For ad-hoc queries or "heavy" background exports that you know will scan old data, you can instruct the query to skip the cache entirely at the session level:
sql
-- Prevents this query from loading new data into the NVMe cache
SET enable_populate_datacache = false;
-- (Optional) Prevents the query from even checking the cache
SET enable_scan_datacache = false;
SELECT ... FROM my_table WHERE event_time < '2023-01-01';
By making this a standard practice for ad-hoc/BI tools querying historical ranges, you can maintain a 100% hit rate for your real-time dashboard queries.
4. Index Management at 40TB
With 40TB of data and 23.4 Billion rows (5.85B per day × 4), the PK index would grow to ~2TB.
* Why Shared-Data is vital here: In a Shared-nothing setup, this 2TB index must be entirely on local SSDs.
* Cloud-Native Persistent Index: By setting "persistent_index_type" = "CLOUD_NATIVE", StarRocks stores the 2TB index on object storage (S3) and only keeps the "hottest" portions of the index in your local NVMe and a small slice of RAM (l0_max_mem_usage). This allows your 6-node cluster to handle 40TB or even 100TB without running out of memory or disk space for indexes.
Summary of Recommendations for 4-Day Retention:
1. Architecture: Shared-data (Cloud-native).
2. Index: Enable CLOUD_NATIVE persistent index.
3. Table Property: Set datacache.partition_duration = "1 day" to strictly prioritize your freshest data in the NVMe.
4. Governance: Use SET enable_populate_datacache = false for large historical scans to preserve the cache for high-concurrency "hot" queries.
References
• best_practices/primarykey_table.md
• table_design/table_types/primary_key_table.md
• knowledge/admin_and_operation/shared_data_compaction.mdMinn Fong
06/04/2026, 2:04 PMRocky
06/04/2026, 2:04 PMMinn Fong
06/04/2026, 3:10 PMRocky
06/04/2026, 3:11 PMrun_mode is a global cluster setting defined in the fe.conf file (either shared_nothing or shared_data).
* Mutually Exclusive: A single StarRocks cluster cannot contain both BE nodes (Shared-nothing) and CN nodes (Shared-data) simultaneously. The metadata management for a Shared-data cluster is fundamentally different because the FE must track data in object storage rather than local disk locations.
* Migration Path: If you want to switch to Shared-data, you would effectively be deploying a new cluster. You cannot "point" an existing Shared-nothing FE at a Shared-data CN. You would need to set run_mode = shared_data in your FE configuration, which would require a fresh metadata initialization.
2. CN Recovery: How the cache "refreshes"
The process for a CN node is actually very similar to a BE node, but with much lower stakes.
Scenario A: Reattaching the same disk (Warm Start)
If a CN node fails (e.g., the EC2 instance dies) and you bring up a new instance with the same NVMe/EBS volume reattached to the same `storage_root_path`:
* Immediate Cache Reuse: When the CN process starts, it scans the starlet_cache (or datacache) directory. It will recognize the existing cache blocks and use them immediately.
* Result: Performance is "warm" from the first second. No data needs to be "refreshed" from S3.
Scenario B: New node with a blank disk (Cold Start)
If you lose the disk or start a fresh node:
* Automatic On-demand Refresh: You don't have to manually "pull" data. As queries come in, the CN checks its local cache. On a "cache miss," it automatically fetches the required data blocks from S3, serves the query, and simultaneously writes those blocks to the local NVMe for the next query.
* Proactive Warmup: If you don't want the first few queries to be slow, you can use the Data Cache Warmup feature (v3.3.0+). You can execute a SQL command to force the cluster to pull specific partitions into the cache:
sql
-- Proactively load the last 24 hours into NVMe
CACHE SELECT * FROM my_table WHERE event_time >= '2023-10-27 00:00:00';
Comparison: BE vs. CN Recovery
Feature | BE (Shared-nothing) | CN (Shared-data)
Data Safety | Depends on local replicas. | 100% safe in S3/Object Storage.
Recovery Goal | Restore data integrity & availability. | Restore performance (warming the cache).
Lost Disk Impact | Severe. Requires data re-balancing/triggering tablet repair from other replicas. | Minor. Performance is "cold" initially, but the node is immediately functional.
Reattach EBS/NVMe | Essential to avoid long re-balancing. | Recommended to avoid "cold" queries, but not strictly required.
Summary: Your intuition to "reattach the disk" is a great practice for CNs as well. It saves S3 egress costs and prevents the "cold start" performance dip. However, unlike a BE, if you can't reattach the disk, the CN will still work perfectly—it will just be a bit slower for the first few minutes as it re-populates the cache from S3.
References
• using_starrocks/caching/block_cache.md
• data_source/data_cache_troubleshooting.md
• data_source/block_cache_warmup.md
• deployment/shared_data/azure.md
• deployment/shared_data/s3.mdMinn Fong
06/04/2026, 3:12 PMRocky
06/04/2026, 3:12 PMCLOUD_NATIVE persistent index. This version of the index is also stored in S3.
* If the CN node goes down and the NVMe is wiped, the new CN node simply pulls the index "image" from S3.
* This makes the "rebuild" process significantly faster and more reliable than a full reconstruction.
Summary of the "Instance Store" Trade-off:
Component | Status if NVMe is wiped | Recovery Action
Table Data | Safe in S3 | None required.
Data Cache | Gone | Automatically re-fills as queries arrive.
PK Index | Gone (Local) | Re-downloaded from S3 (if using CLOUD_NATIVE index).
Subjective Take: Most users at your scale prefer ephemeral NVMe instance stores because they are significantly faster and cheaper than EBS. They accept the "warm-up" period after a node failure in exchange for much higher performance and lower costs during the 99.9% of the time the cluster is healthy.
References
• introduction/Architecture.md
• deployment/shared_data/s3.md
• using_starrocks/caching/block_cache.md
• administration/management/resource_management/Replica.md
References
• deployment/shared_data/s3.md
• using_starrocks/caching/block_cache.md
• deployment/shared_data/minio.mdMinn Fong
06/04/2026, 3:23 PMRocky
06/04/2026, 3:23 PMdatacache.partition_duration (formerly known as storage_cache_ttl) is the specific mechanism in StarRocks Shared-data clusters designed to solve exactly what you are describing.
1. How datacache.partition_duration Works
This property allows you to define a "Hot Data Window." Instead of letting the cache fill up with every random piece of data a user touches, StarRocks uses this setting to filter what is allowed to be cached.
* Mechanism: When a query runs, StarRocks checks the partition's timestamp. If the data is older than the partition_duration (e.g., 30 DAY), the system will read it from S3 but will not write it to the NVMe cache.
* Result: Rogue queries scanning historical data ("Give me the last 3 years of logs") will still be slow because they pull from S3, but they cannot evict your recent, hot data from the NVMe. This keeps your "dashboard" performance stable.
Example Table Setup:
sql
CREATE TABLE my_table ( ... )
PROPERTIES (
"datacache.enable" = "true",
"datacache.partition_duration" = "7 DAY" -- Only cache the last 7 days of data
);
2. Multi-Layered Protection Against Thrashing
While partition_duration handles the "historical data" problem, StarRocks includes two other features to protect against "rogue queries" that scan large amounts of recent data:
* SLRU (Segmented LRU) Policy: StarRocks doesn't just use a simple LRU. Its SLRU strategy divides the cache into a "Protection Segment" and an "Eviction Segment."
* New data (from a rogue query) enters the Eviction Segment first.
* Data only moves to the Protection Segment if it is accessed multiple times.
* This prevents a "one-off" large scan from wiping out your truly hot, frequently used dashboard data.
* Session-Level Bypass: If you know a specific batch job or "power user" is about to run a massive scan that would normally be cached, you can force that specific session to bypass the cache entirely:
sql
SET skip_local_disk_cache = true; -- (v3.3.9+) Bypasses NVMe cache
SELECT ... ;
3. Subjective Reality: Is it a "Total" Solution?
It is a 90% solution. It perfectly solves the "scanning old data" thrashing.
However, if a rogue query scans a massive amount of data within your hot window (e.g., a query for the last 24 hours that accidentally scans every single column and row), it could still put pressure on the cache. In those cases, the SLRU and Resource Groups (to limit the CPU/IO of that rogue user) are your second and third lines of defense.
Recommendation: For your 40TB scale, set the partition_duration to the smallest window that covers your primary dashboard/API needs (e.g., 3 DAY or 7 DAY). This ensures your NVMe instance stores are utilized only for the highest-value data.
References
• deployment/shared_data/s3.md
• deployment/shared_data/feature-support-shared-data.md
• data_source/data_cache.md
• sql-reference/System_variable.md
• using_starrocks/caching/block_cache.md
References
• data_source/data_cache.md
• using_starrocks/caching/query_cache.mdMinn Fong
06/04/2026, 3:33 PMRocky
06/04/2026, 3:34 PMlake_compaction_max_tasks: Default is -1 (Auto-calculated as CN_nodes * 16). If your scores are high, you can increase this to allow more partitions to compact at once.
* lake_ingest_slowdown_threshold: Default is 100. If a partition score hits this, StarRocks slows down writes to let compaction catch up.
* lake_compaction_score_selector_min_score: Default is 10.0. Compaction only triggers if the score is above this.
CN Tuning (Per Node)
* compact_threads: (Default 4). For a high-throughput cluster, it is recommended to set this to 25% of your CPU cores (e.g., if you have 32-core machines, set this to 8 or 12).
* max_cumulative_compaction_num_singleton_deltas: The docs recommend reducing this to 100 (from 500) for Shared-data. This makes each task smaller and faster, preventing "stuck" long-running compactions.
4. How to monitor it
In Shared-data, you don't look at individual BE logs as much. You use:
sql
-- View global scores (Look for MaxCS)
SELECT * FROM information_schema.partitions_meta ORDER BY MAX_CS DESC;
-- View active tasks and their progress (%)
SELECT * FROM information_schema.be_cloud_native_compactions;
-- View history of compaction tasks
SHOW PROC '/compactions';
Summary Recommendation
In your new Shared-data cluster, you can likely stop the aggressive interval tuning. Start with the default settings, but increase your compact_threads and set max_cumulative_compaction_num_singleton_deltas = 100. If you see scores hitting 100+, just spin up more CN nodes—compaction will automatically distribute to them and clear the backlog.
References
• administration/management/compaction.md
• knowledge/admin_and_operation/shared_data_compaction.md
• deployment/shared_data/feature-support-shared-data.md
• faq/shared_data_faq.md
ReferencesRocky
06/04/2026, 3:34 PMMinn Fong
06/04/2026, 3:36 PMRocky
06/04/2026, 3:36 PMlake_enable_vertical_compaction_fill_data_cache) that allows the result of the compaction to be written directly into the local NVMe cache. This means the next query hits the "compacted" data at local speeds immediately.
3. Scaling out "fixes" compaction instantly
In Shared-nothing, if compaction scores hit 250, you have to wait for the background threads to catch up or add nodes (which triggers a heavy data rebalance).
* Shared-data Reality: If you see your MaxCS rising, you can spin up 4 more CN nodes. These nodes will immediately begin pulling tasks from the FE and clearing the backlog. Once the scores are back to 10, you can turn those nodes off. You are essentially "throwing temporary compute" at the compaction problem.
4. Recent Optimizations (v3.3 and v3.5)
StarRocks has specifically targeted the "S3 API cost/overhead" you are worried about:
* Sized-Tiered Compaction: For Primary Key tables, this strategy significantly reduces write amplification (how many times a piece of data is re-written).
* File Bundling (v3.5+): StarRocks now bundles multiple small metadata/index updates into single S3 objects. This reduces S3 PUT costs by up to 90%, making high-frequency compaction much cheaper.
Summary: Comparison for your 500MB batching
Feature | Shared-nothing (Current) | Shared-data (Proposed)
Backlog Risk | High (stuck on specific BEs) | Low (distributed to any CN)
Resource Impact | Direct (compaction steals query IO) | Isolated (can use dedicated CNs)
Tuning Focus | Interval & Thread count | Concurrency (lake_compaction_max_tasks)
Ingest Penalty | High (Versions block writes) | Managed (FE slows down commits gracefully)
Subjective Take: Because you are already doing 500MB batches, you have already solved the hardest part of StarRocks ingestion. In Shared-data, you will find that "Compaction Score" is something you solve with horizontal scaling rather than complex per-node thread tuning.
References
• administration/management/compaction.md
• knowledge/admin_and_operation/shared_data_compaction.md
• faq/shared_data_faq.md
• deployment/shared_data/feature-support-shared-data.md
References
• administration/management/compaction.mdRocky
06/04/2026, 3:36 PMMinn Fong
06/05/2026, 4:30 PMRocky
06/05/2026, 4:30 PMCACHE SELECT command. You can run this immediately after a node comes up to force it to pull hot data into the NVMe:
sql
-- Warm up the last 3 days of data for a specific table
CACHE SELECT * FROM sales_table WHERE dt >= '2024-01-01';
* Ingestion Warming: Any new data being loaded (Stream Load, etc.) while the CN is active is automatically written to the local cache as it is uploaded to S3.
4. Zero Rebalancing "Pain"
In Shared-nothing, adding or replacing nodes triggers Tablet Rebalancing, which is the most common cause of performance degradation during maintenance.
In Shared-data, there is no rebalancing. The FE simply starts sending 1/Nth of the query fragments to the new CN. If the CN goes away, the FE immediately redistributes those fragments to other nodes.
Summary: Your intuition is correct—recovering a CN node is more like "recovering a stateless microservice" than "recovering a database node." Asynchronous Database node."
References
• introduction/Architecture.md
• deployment/shared_data/feature-support-shared-data.md
• data_source/block_cache_warmup.md
• quick_start/shared-data.md
References
• deployment/shared_data/feature-support-shared-data.md
• data_source/block_cache_warmup.md
• knowledge/admin_and_operation/shared_data_compaction.mdMinn Fong
06/05/2026, 5:15 PMRocky
06/05/2026, 5:15 PMdatacache.partition_duration table property.
While you asked for "n" partitions, StarRocks defines this cache policy using a time-based duration (e.g., last 3 days, last 1 month). If your partitions are daily, setting the duration to "3 DAY" effectively keeps only the most recent 3 partitions in the NVMe cache.
Property Details
* Property Name: datacache.partition_duration (Note: In v3.0, this was named storage_cache_ttl).
* Function: It defines a "hot data window." Only data belonging to partitions within this window (calculated from the current time) will be cached on the local NVMe disks.
* Units: You can use YEAR, MONTH, DAY, or HOUR.
Example Implementation
If you want to ensure only the last 7 days of data are held in the cache:
sql
CREATE TABLE orders (
order_id BIGINT,
order_date DATE,
...
)
PARTITION BY RANGE(order_date) (...)
PROPERTIES (
"datacache.enable" = "true",
"datacache.partition_duration" = "7 DAY"
);
How it works with NVMe
1. Automatic Eviction: As time moves forward, older partitions naturally "fall out" of the partition_duration window. If the local NVMe disk becomes full, these older blocks are the first candidates for eviction.
2. Accessing Cold Data: If you query a partition older than 7 days, StarRocks will read it directly from S3. It will not populate the NVMe cache with this data, preserving the cache space for your "hot" partitions.
3. Updating the Policy: You can change this window at any time without a restart:
sql
ALTER TABLE orders SET ("datacache.partition_duration" = "14 DAY");
Comparison Note (Materialized Views)
If you are using Materialized Views as a caching layer, StarRocks does support a count-based property called partition_ttl_number, which explicitly keeps the last "n" partitions. However, for the base table's block cache (NVMe), the time-based partition_duration is the standard approach.
References
• deployment/shared_data/s3.md
• using_starrocks/caching/block_cache.md
• deployment/shared_data/feature-support-shared-data.md
• sql-reference/sql-statements/data-definition/CREATE_TABLE.md
References
• deployment/shared_data/feature-support-shared-data.md
• knowledge/admin_and_operation/shared_data_compaction.mdMinn Fong
06/05/2026, 5:20 PMRocky
06/05/2026, 5:20 PMi4i is the Winner
Your inclination toward i4i instances is correct. They are widely considered the ideal family for StarRocks CN nodes for several reasons:
* High-Performance NVMe: The local AWS Nitro SSDs on i4i provide the massive IOPS and low latency required for both the Data Cache and the Persistent Index Cache. This effectively hides the S3 latency.
* Memory-to-vCPU Ratio: i4i provides 8GB of RAM per vCPU, which is perfect for the memory-intensive nature of PK table joins and index management.
* Networking: They offer high networking bandwidth (up to 75Gbps), which is critical for the "Fetch-Merge-Upload" cycle of shared-data compaction.
Alternative: If i4i is unavailable, look at m6id or c6id instances, which also feature local NVMe storage. Avoid standard m6i or r6i without local disks for this workload, as EBS-only caching will significantly degrade your partial update performance.
Implementation Tip
When you set up your PK tables in Shared-data, ensure you enable the cloud-native persistent index:
sql
PROPERTIES (
"enable_persistent_index" = "true",
"persistent_index_type" = "CLOUD_NATIVE"
);Rocky
06/05/2026, 5:20 PMi4i nodes, the PK index doesn't have to be rebuilt from scratch, and the cluster remains operational recovery remains "warm-up" time is minimized.
References
• deployment/plan_cluster.md
• deployment/shared_data/feature-support-shared-data.md
• introduction/Architecture.mdMinn Fong
06/05/2026, 5:23 PMRocky
06/05/2026, 5:23 PM__row column. It is essentially an append-heavy operation. The "Apply" duration is significantly lower because it doesn't need to perform the fine-grained columnar merge during the write path. It defers the merging cost to the Compaction phase or Query phase.
Recommendation: For 9 different schemas and high throughput, Row Mode is likely your best bet to keep ingestion latency low. You can force this in your table properties:
sql
PROPERTIES (
"partial_update_mode" = "row"
);
──────────
2. Shared-Data vs. Shared-Nothing for PK Updates
Feature | Shared-Nothing (BE) | Shared-Data (CN)
Compaction Bottleneck | Local. If one node gets a "hot" partition with 9 update schemas, its compaction score will spike, eventually blocking all writes to that tablet. | Distributed. The FE can schedule the compaction of that hot partition on any CN node in the cluster, preventing single-node exhaustion.
Scaling | Requires "Tablet Rebalancing," which moves heavy PK data and indexes between nodes, killing performance during the move. | Instant. Add a CN node, and it immediately starts helping with the compaction and query load. No data movement required.
Persistent Index | Tied to local disk. If the BE dies, the index is lost and must be rebuilt or recovered via EBS remount. | Cloud-Native. The index is stored on S3 and cached on your local NVMe. If a node dies, the index is instantly available to the next node.
──────────
3. Recommendation & Instance Family
Recommendation: Shared-Data + Row Mode + i4i Instances
* Architecture: Use Shared-Data. High-throughput PK updates with partial schemas live and die by Compaction. Shared-data is the only architecture that lets you "throw more compute" at a compaction backlog without rebalancing the whole database.
* Storage Mode: Start with Row Mode. Since your schemas are varied, Row Mode will provide the most stable "Commit Apply" duration.
* EC2 Instance: i4i is the gold standard.
* NVMe for DCache: Your partial updates still need to read "original" rows to handle the logic. Having these in the i4i NVMe cache is 10-100x faster than fetching from S3.
* NVMe for Persistent Index: PK tables require a persistent index to avoid OOM. The i4i local SSD is perfect for the Cloud-Native Persistent Index Cache, ensuring that "point lookups" (required for every UPSERT) happen at sub-millisecond speeds.
Ideal Table Setup:
sql
CREATE TABLE my_table (
pk_id BIGINT,
...
) PRIMARY KEY (pk_id)
DISTRIBUTED BY HASH(pk_id)
PROPERTIES (
"enable_persistent_index" = "true",
"persistent_index_type" = "CLOUD_NATIVE",
"partial_update_mode" = "row",
"datacache.enable" = "true"
);
Summary of Pros/Cons
* Shared-Nothing:
_ _Pro:* Absolute minimum latency for small tables.
_ _Con:* "Compaction death spirals" on hot nodes; scaling is a nightmare.
* Shared-Data:Rocky
06/05/2026, 5:23 PMMinn Fong
06/05/2026, 5:28 PMRocky
06/05/2026, 5:28 PMPUTs per Transaction ≈ Number of Tablets Touched.
* If your load touches 20 different tablets (buckets), StarRocks will likely perform 20 S3 PUTs—one for each segment file created in those tablets.
* Even if the transaction is small, each tablet needs its own file.
2. Primary Key Table Overhead
Because you are using Primary Key tables with partial updates, there is additional metadata:
* Del Files: If an update invalidates existing rows, StarRocks may write "Delete Bitmap" files to S3.
* Cloud-Native Persistent Index: If you use the CLOUD_NATIVE index type (recommended for i4i instances), the index itself is periodically synced to S3. This adds background PUT operations that aren't tied directly to the ingestion TPS.
3. Metadata & Versioning
Every transaction commit involves a "Publish Version" step.
* By default, this involves metadata updates.
* Optimization: In newer versions (v3.2.3+), you can enable lake_enable_batch_publish_version. This allows the Frontend (FE) to batch multiple transaction commits into a single metadata update, which can significantly reduce S3 PUTs for the metadata portion of the load.
4. The Compaction "Tax"
This is the most significant source of S3 PUTs that is not captured by your ingestion TPS.
* Compaction runs in the background to merge the small files created by your high-frequency ingestion.
* Every time a compaction task runs, it reads several old files and performs a PUT for a new, larger merged file.
* In a high-throughput scenario with 9 different partial update schemas, your compaction overhead will be high, meaning a large percentage of your total S3 PUTs will come from background maintenance rather than the initial load.
5. Recommendation for Estimation
If you want to estimate your S3 costs/operations from your current Shared-nothing cluster:
1. Check Average Tablets per Load: See how many tablets are typically involved in your average transaction.
2. Estimate S3 PUTs: (TPS _ Avg_Tablets_Touched) _ 1.5. (The 1.5 multiplier is a rough "rule of thumb" to account for metadata and compaction overhead).
3. Monitor the specific metric: If you set up a POC, look for the metric fslib_s3_single_upload_iops. This is the literal count of S3 PutObject calls.
Summary
* Shared-nothing TPS tells you how many times you "pushed the button."
* Shared-data S3 PUTs tells you how many files were actually moved to the cloud.
Because of the Tablet Multiplier and Compaction, your S3 PUTs will likely be 10x to 50x higher than your TPS if you have a high bucket count and frequent small commits.
References
• administration/management/monitoring/metrics-shared-data.md
• knowledge/admin_and_operation/shared_data_compaction.md
• knowledge/usage/load/shared_data_batch_ingestion.md
• faq/shared_data_faq.md
References
• deployment/shared_data/s3.md
• knowledge/usage/load/shared_data_batch_ingestion.md
• table_design/table_types/primary_key_table.mdMinn Fong
06/05/2026, 6:56 PMRocky
06/05/2026, 6:57 PM/api/transaction/begin to get a label, then call /api/transaction/load repeatedly as data arrives on the gRPC stream. Finally, call /api/transaction/commit.
* Why: Ideal if you want to group a long-running gRPC stream into one atomic transaction without holding all the data in your service's RAM.
* Strategy C: Merge Commit (v3.4+)
* How: Enable enable_merge_commit in the Stream Load header.
* Why: If you have many concurrent gRPC streams sending small amounts of data, StarRocks will automatically merge these independent HTTP requests into a single transaction/version on the backend. This significantly reduces S3 PUTs and "too many versions" errors in Shared-data clusters.
──────────
2. Critical Configuration for your use case
To make this work efficiently with high-throughput PK tables and 9 different schemas:
* Batching is non-negotiable: In Shared-data, each Stream Load commit creates at least one file on S3. Aim for 10MB to 100MB per load. If you load 1KB every second, your S3 costs and compaction overhead will skyrocket.
* Transaction Batching (v3.2.3+):
Ensure this is enabled on your FE to reduce the metadata overhead of frequent commits:
sql
ADMIN SET FRONTEND CONFIG ("lake_enable_batch_publish_version" = "true");
* Handle Ordering: Since you are using Primary Key tables, gRPC streams can sometimes deliver data out-of-order (especially if you have multiple service instances).
* Recommendation: Use a Sequence Column (e.g., a timestamp or incrementing ID from the source).
* In your table DDL: PROPERTIES ("function_column.sequence_col" = "your_timestamp_column").
* This ensures that even if an "older" gRPC message arrives after a "newer" one, the newer data is preserved.
3. Why not Routine Load?
You could push your gRPC data to Kafka and use Routine Load, but:
1. Latency: It adds another hop.
2. Complexity: You have to manage Kafka.
3. Control: With Stream Load in your gRPC service, you can implement back-pressure (e.g., if StarRocks returns a "compaction score too high" error, your service can slow down the gRPC consumption).
Final Recommendation
Implement Manual In-Memory Batching (Strategy A) in your gRPC service. It gives you the best control over memory and S3 PUT costs. If your service has very high concurrency (many callers), upgrade to StarRocks v3.4+ and use the Merge Commit feature to let StarRocks handle the batching for you.
References
• loading/StreamLoad.md
• loading/Stream_Load_transaction_interface.md
• knowledge/usage/load/shared_data_batch_ingestion.md
• loading/Load_to_Primary_Key_tables.md
ReferencesRocky
06/05/2026, 6:57 PMMinn Fong
06/05/2026, 7:06 PMRocky
06/05/2026, 7:07 PMi4i NVMe drives and S3:
1. The Mandatory S3 Write (Durability)
In the Shared-Data architecture, S3 (or any object storage) is the "Source of Truth."
* Every compaction task must produce a new version of the data.
* This version must be written to S3 so that other nodes (or a new node after a crash) can see it.
* If StarRocks only wrote to local NVMe, the cluster would lose its "Shared-Data" property, and your data would be at risk if that specific node failed.
2. The NVMe "Read" Advantage (Speed)
This is where your i4i instances shine. If your active data fits in the NVMe:
* Zero S3 Reads: Compaction will read the source files directly from the Data Cache (NVMe). This is a massive performance boost because it avoids the latency and API cost of fetching data from S3.
* CPU/RAM Merging: The actual merging of rows happens in-memory. Because the I/O is coming from local NVMe, the compaction process becomes CPU-bound rather than I/O-bound, allowing it to finish much faster.
3. "Compaction Fill Cache" (The Performance Loop)
There is a specific optimization you should ensure is enabled: lake_enable_vertical_compaction_fill_data_cache = true.
* When this is enabled, as the CN node writes the newly compacted file back to S3, it simultaneously writes it into the local NVMe cache.
* Result: The very first query that needs that new data after compaction will find it already "warm" in the NVMe. It never has to go to S3 to "fetch" the results of the compaction.
4. Impact on Primary Key Tables (The "Index" Factor)
Since you are using Primary Key tables with 9 schemas, your compaction involves checking the Persistent Index.
* Cloud-Native Persistent Index: In Shared-Data mode, the index itself is a file on S3.
* If the index for the tablet you are compacting is already in the NVMe cache, the "lookup" phase of compaction (where it maps old versions to new versions) happens at sub-millisecond speeds.
* If the index was not in the NVMe, compaction would have to wait for S3 to provide the index pieces, significantly slowing down the "Apply" and "Merge" phases.
Summary: Does it make things faster?
Absolutely. If your data fits in the NVMe:
1. Compaction "Read" Latency: S3 (10ms+) → NVMe (0.1ms).
2. Compaction "Write" Latency: Remains "S3 speed" for the commit, but the throughput is higher because the system isn't waiting on reads.
3. Query Latency: The new compacted data is immediately available in NVMe, avoiding the "first-read penalty" after a compaction.
Pro-tip: Monitor the metric datacache_read_bytes vs remote_read_bytes during compaction. If remote_read_bytes is 0, your NVMe is doing its job perfectly and your compaction is as fast as it can possibly be.
References
• faq/shared_data_faq.md
• knowledge/admin_and_operation/shared_data_compaction.md
• administration/management/compaction.md
• deployment/shared_data/feature-support-shared-data.md
References
• knowledge/admin_and_operation/shared_data_compaction.md
• faq/shared_data_faq.mdMinn Fong
06/08/2026, 1:42 PMRocky
06/08/2026, 1:42 PMlake_enable_vertical_compaction_fill_data_cache (Default: true).
* Mechanism: As the CN streams the new compacted data to S3, it simultaneously writes a copy into your local NVMe.
* Benefit: The "next" round of compaction (or any user query) will find this new version already sitting on the NVMe.
3. Primary Key Index Performance
Since you are using Primary Key tables, compaction also involves the Persistent Index.
* In Shared-data mode, the index is also a file stored in S3.
* However, just like data files, StarRocks caches the index files in the ${storage_root_path}/persist/ directory on your NVMe.
* With "plenty of NVMe," these index lookups (which happen during every compaction to handle row updates) will stay entirely local, avoiding the heavy latency of fetching index "shards" from S3.
Summary of the "NVMe-Rich" Workflow:
Operation | Source/Target | Latency | S3 Cost
Read old data | NVMe Cache | Microseconds | $0
Read Index | NVMe Cache | Microseconds | $0
Merge rows | CPU / RAM | Nanoseconds | $0
Write new data | S3 + NVMe Cache | Network Latency* | PUT Cost
_\_The write to S3 is typically done in the background/asynchronously during the load or compaction commit, so it rarely blocks the compute process if your network bandwidth is healthy.*
Is there any catch?
The only time you would still see S3 reads is if:
1. A node restarts: The cache is persistent, but if the metadata becomes inconsistent, it might re-verify a block from S3.
2. Metadata fetches: The FE still needs to talk to S3/the object store for "list" operations and some metadata updates, but these are tiny compared to the data volume.
Conclusion: With enough NVMe to house your data, you have the best of both worlds: the cost/scalability of S3 for storage, with the local performance of NVMe for the heavy lifting of compaction and queries.
References
• administration/management/BE_configuration.md
• knowledge/admin_and_operation/shared_data_compaction.md
• using_starrocks/caching/block_cache.md
• data_source/data_cache.md
References
• administration/management/BE_configuration.md
• data_source/data_cache.md
• deployment/shared_data/feature-support-shared-data.md
• using_starrocks/caching/block_cache.md
• sql-reference/System_variable.mdMinn Fong
06/08/2026, 1:45 PMRocky
06/08/2026, 1:45 PMDataCacheReadBytes (and related metrics like DataCacheWriteBytes) represents only the data read/written for that specific query.
* It does not include compaction.
* It tells you exactly how much of your query's data was served from the NVMe/Memory cache versus being fetched from S3.
2. If you see it in a System Dashboard (Prometheus)
If you are looking at a Grafana dashboard with a label like datacache_read_bytes, this usually maps to the BE metric block_cache_hit_bytes.
* For Shared-data (3.x) clusters: Most system-wide "Data Cache" metrics track all reads going through the cache layer. In this architecture, compaction does read from the cache (if the data is local) and the new compacted files are written back into the cache.
* However, to avoid confusing "background work" with "user performance," StarRocks provides separate metrics for compaction:
* `compaction_bytes_total`: The total throughput of compaction (merged data).
* `be_cumulative_compaction_bytes_per_second`: The current speed of background merging.
How to distinguish them?
If you want to know if compaction is hitting your NVMe cache, don't look at DataCacheReadBytes. Instead, observe these two together:
1. compaction_bytes_total: This shows how much work compaction is doing.
2. fslib_total_read_data (or S3 Get requests): If your compaction throughput is high but your S3 "GET" requests are low, it confirms that compaction is successfully reading from your local NVMe cache instead of S3.
Summary
* DataCacheReadBytes (Profile): Queries only.
* block_cache_hit_bytes (Prometheus): Total hits, but often used for query hit-rate analysis.
* Compaction Reads: Effectively "invisible" in query-specific metrics, but they do physically use the same NVMe cache and are tracked by dedicated compaction throughput metrics.
References
• data_source/data_cache.md
• administration/management/monitoring/metrics.md
• data_source/data_cache_observe.md
• using_starrocks/caching/block_cache.md
References
• administration/management/monitoring/metrics.mdMinn Fong
06/08/2026, 2:21 PMRocky
06/08/2026, 2:22 PMlake_autovacuum_grace_period_minutes, default 30 mins).
* The Deletion Call: After the grace period, the Vacuum process (running on the CN nodes, but managed by the FE) makes the actual S3 DeleteObjects calls to physically remove the old files.
_ _Cost Note:* Because StarRocks uses the DeleteObjects (multi-object delete) API, it batches these calls to minimize S3 request costs.
──────────
2. How is data shared and rebalanced across CN nodes?
StarRocks uses a Consistent Hashing mechanism (within a component called Starlet) to map Tablets to specific CN nodes. It does not use a simple "modulo" of the total node count.
Does it use the Distribution Key?
Indirectly, yes.
1. Your Distribution Key determines which Tablet a row belongs to (e.g., order_id 123 -> Tablet 4001).
2. The Consistent Hashing algorithm then maps Tablet 4001 to CN Node A.
3. Therefore, all data for that specific bucket will always be processed and cached on CN Node A. This ensures that the NVMe cache is highly efficient—you don't have multiple nodes caching the same data.
What happens when a CN node goes down?
Because it uses Consistent Hashing (and not a simple modulo), the "Reshuffle" is minimized:
* The "Modulo" Nightmare (Avoided): In a simple TabletID % N system, if you go from 10 nodes to 9, almost every tablet would change owners, and your entire cluster's cache would become cold.
* The StarRocks Way: When a CN node goes down, only the tablets that were assigned to that specific node are redistributed among the remaining nodes.
* The Impact:
1. The remaining $n-1$ nodes keep their current cache; they don't lose anything they already have.
2. The $n-1$ nodes will "inherit" the orphaned tablets from the dead node.
3. The Fetch: Those specificinherited tablets will indeed be "cold" on their new nodes. The first time they are queried/compacted, the new owner node will fetch that data from S3 and write it to its own local NVMe.
Summary: If you have 10 nodes and 10TB of data, each node will roughly house 1TB of unique data in its NVMe. If one node dies, the other 9 nodes will continue to serve their own 9TB from cache, and only the 1TB from the dead node will trigger new S3 reads as it is re-cached across the survivors.
References
• faq/shared_data_faq.md
• knowledge/admin_and_operation/shared_data_compaction.md
• deployment/shared_data/s3.md
• introduction/Architecture.md
• using_starrocks/caching/block_cache.md
References
• deployment/shared_data/s3.md
• deployment/shared_data/azure.md
• deployment/shared_data/feature-support-shared-data.md
• deployment/shared_data/minio.mdRocky
06/08/2026, 2:22 PMMinn Fong
06/08/2026, 2:36 PMRocky
06/08/2026, 2:37 PMADMIN SET FRONTEND CONFIG ("enable_trace_historical_node" = "true");
2. System Variable: SET GLOBAL enable_datacache_sharing = true;
4. Proactive Warming (v3.3.0+)
If you don't want to wait for queries to "pull" the data back into the recovered node's cache, you can use the Data Cache Warmup feature.
* You can run a CACHE SELECT statement to explicitly tell the recovered node to pre-fetch specific tables or partitions into its NVMe cache.
Summary: Tablets go back to their "rightful" owner automatically. The "temporary" cache stays until evicted by LRU. With Cache Sharing enabled, the recovered node will heal its cache by talking to its peers instead of hammering S3.
References
• data_source/data_cache.md
• deployment/shared_data/feature-support-shared-data.md
• using_starrocks/caching/block_cache.md
• faq/shared_data_faq.md
• administration/management/FE_configuration.md
References
• data_source/data_cache.md
• deployment/shared_data/feature-support-shared-data.md
• using_starrocks/caching/block_cache.mdRocky
06/08/2026, 2:37 PMMinn Fong
06/08/2026, 2:46 PMRocky
06/08/2026, 2:47 PMstarrocks_fe_tablet_max_compaction_score: The most critical metric. If this exceeds 100, StarRocks starts slowing down ingestion. If it exceeds 2000, ingestion may stop.
* starrocks_be_lake_delta_writer_queue_size: Monitor the async writer queue. A growing queue indicates the BE is struggling to flush data to the object store.
* starrocks_be_lake_publish_version_latency: Measures the time to commit a version. High latency here delays data visibility and can cause transaction timeouts.
2. Primary Key Performance (Memory & Index)
PK tables use a "Delete Vector" and an "Index" to manage upserts.
* starrocks_be_mem_tracker{type="update"}: Tracks memory used by PK indexes and delete vectors. High values indicate the PK index is taking up significant BE memory.
* starrocks_be_lake_pk_index_write_bytes / starrocks_be_lake_pk_index_read_bytes: (Introduced in recent versions) Monitor the I/O throughput of the persistent PK index (stored on NVMe/S3).
* starrocks_be_lake_delvec_cache_miss_per_minute: High miss rates for the delete vector cache will cause query and ingestion slowdowns as the BE has to fetch delete metadata from S3.
3. Shared-Data Metadata (FE/BE)
Metadata management in shared-data clusters is more intensive.
* starrocks_be_lake_get_tablet_metadata_latency: High latency here means the BE is slow to pull tablet info from the metadata service, affecting both queries and ingestion.
* starrocks_be_lake_metadata_cache_miss_per_minute: Monitor the hit rate of the local metadata cache. Frequent misses increase S3 calls.
4. Data Cache & Object Storage I/O
Since data lives in S3, the local NVMe cache hit rate determines your performance.
* starrocks_be_block_cache_hit_bytes / starrocks_be_block_cache_lookups_total: High hit rates are essential for query performance.
* starrocks_be_fslib_read_throughput / starrocks_be_fslib_write_throughput: Represents the actual throughput to your object store (S3/OSS/Azure Blob). Use this to see if you are hitting bandwidth limits of your cloud provider.
* starrocks_be_fslib_read_io_latency: Monitor S3 "GET" latency. Spikes here usually indicate cloud provider throttling or network congestion.
5. Vacuum (Cleanup)
* starrocks_be_lake_vacuum_delete_total: Number of objects deleted from S3.
* starrocks_be_lake_vacuum_errors_total: Monitor for failures in cleaning up old versions to avoid unexpected S3 storage costs.
Summary Checklist for Grafana
Category | Metric Name | Warning Sign
Ingestion | starrocks_fe_tablet_max_compaction_score | Value > 100
Commit | starrocks_be_lake_publish_version_latency | Sharp upward trend
Memory | starrocks_be_mem_tracker{type="update"} | Reaching BE memory limit
Cache | starrocks_be_block_cache_hit_ratio | Value < 80% (for hot data)
S3 IO | starrocks_be_fslib_read_io_latency | Latency > 100ms
References
• administration/management/monitoring/metrics-shared-data.md
• best_practices/primarykey_table.md
• knowledge/admin_and_operation/shared_data_compaction.md
• administration/management/monitoring/metrics.md
References
• administration/management/monitoring/metrics.mdRocky
06/08/2026, 2:47 PMMinn Fong
06/08/2026, 3:12 PMRocky
06/08/2026, 3:13 PMstarrocks_be_ prefix or if you haven't enabled certain features.
There are three main reasons why you might not see these specific metrics:
1. Naming Differences (The "Starlet" Prefix)
In shared-data clusters, many I/O and Cache metrics come from the Starlet library and often do not follow the standard starrocks_be_ prefix. Check for these names instead:
* For Throughput: Look for starrocks_be_fslib_read_throughput or simply fslib_read_throughput.
* For Cache Hits: Instead of starrocks_be_block_cache_hit_bytes, look for starrocks_be_datacache_read_block_count or starrocks_be_datacache_read_block_bytes.
* Note on Page Cache: StarRocks has both a "Page Cache" (for storage segments) and a "Data Cache" (for S3 blocks). Ensure you are looking for datacache metrics if you are using a shared-data cluster.
2. Some Metrics are only in the JSON API (Common in older 3.x versions)
In some StarRocks versions, detailed Data Cache statistics were not exposed to the standard Prometheus /metrics endpoint by default. They were only available via a JSON endpoint:
* Endpoint: http://<BE_IP>:<BE_HTTP_PORT>/api/datacache/stat
* If missing in Prometheus: You may need to use a sidecar exporter or upgrade to a more recent version (v3.3+) where more of these have been bridged to the standard Prometheus endpoint.
3. Feature Configuration
Some metrics only appear if the corresponding feature is active and has actually processed data:
* Data Cache: If enable_datacache = false (default is usually true in shared-data CN nodes), the datacache_ and block_cache_ metrics will not be initialized.
* Throughput Metrics: fslib_read_throughput is often specific to S3/Object Storage access. If you are querying data that is already fully cached, the "fslib" (filesystem library) might not report remote throughput because it's only reading from local NVMe.
Recommended Troubleshooting Steps
1. Check the Raw Endpoint: Run curl http://<BE_IP>:8040/metrics | grep block_cache to see exactly what strings the BE is exporting. This bypasses any Grafana/Prometheus labeling issues.
2. Use the Shared-Data Dashboard: StarRocks provides a specific Starlet Dashboard template. If you are using the standard "StarRocks-BE" dashboard, it often lacks these cloud-native specific metrics.
3. Verify Variable: Ensure you are looking for starrocks_be_lake_... metrics for ingestion (e.g., starrocks_be_lake_publish_version_latency), as these are the primary drivers for PK table performance in shared-data mode.
Try searching for these specific strings in your Prometheus explorer:
* starrocks_be_datacache_read_bytes
* starrocks_be_datacache_hit_bytes
* starrocks_be_fslib_read_io_latency
* starrocks_be_lake_delta_writer_queue_size
References
• administration/management/monitoring/metrics-shared-data.md
• data_source/data_cache_observe.md
• using_starrocks/caching/block_cache.md
• administration/management/monitoring/metrics.md
References
• data_source/data_cache_observe.md
• administration/management/monitoring/metrics-shared-data.md
• using_starrocks/caching/block_cache.md
• administration/management/monitoring/metrics.md
ReferencesMinn Fong
06/08/2026, 3:21 PMstarrocks_be_page_cache_hit_count 151896739439
# TYPE starrocks_be_query_cache_hit_count gauge
starrocks_be_query_cache_hit_count 0
# TYPE starrocks_be_query_cache_hit_ratio gauge
starrocks_be_query_cache_hit_ratio 0.000000
# TYPE starrocks_be_vector_index_cache_hit_count gauge
starrocks_be_vector_index_cache_hit_count 0
# TYPE starrocks_be_vector_index_cache_hit_ratio gauge
starrocks_be_vector_index_cache_hit_ratio 0.000000
# HELP default_cache_hit_bytes
# TYPE default_cache_hit_bytes gauge
default_cache_hit_bytes 0
# HELP default_cache_hit_bytes_last_minite
# TYPE default_cache_hit_bytes_last_minite gauge
default_cache_hit_bytes_last_minite 0
# HELP default_cache_hit_count
# TYPE default_cache_hit_count gauge
default_cache_hit_count 0
# HELP default_cache_hit_count_last_minite
# TYPE default_cache_hit_count_last_minite gauge
default_cache_hit_count_last_minite 0
# HELP lake_delvec_cache_hit_minute
# TYPE lake_delvec_cache_hit_minute gauge
lake_delvec_cache_hit_minute 0
# HELP lake_metadata_cache_hit_minute
# TYPE lake_metadata_cache_hit_minute gauge
lake_metadata_cache_hit_minute 0
# HELP lake_schema_cache_hit_minute
# TYPE lake_schema_cache_hit_minute gauge
lake_schema_cache_hit_minute 0
# HELP lake_segment_cache_hit_minute
# TYPE lake_segment_cache_hit_minute gauge
lake_segment_cache_hit_minute 0
# HELP lake_txn_log_cache_hit_minute
# TYPE lake_txn_log_cache_hit_minute gauge
lake_txn_log_cache_hit_minute 0
# HELP merge_commit_txn_cache_hit_total
# TYPE merge_commit_txn_cache_hit_total gauge
merge_commit_txn_cache_hit_total 0
100 241963 100 241963 0 0 46168# HELP table_schema_service_schema_cache_hit
k# TYPE table_schema_service_schema_cache_hit gauge
table_schema_service_schema_cache_hit 0
0# HELP fslib_open_cache_hits Count how many hits to cache file when opening a file for read.
# TYPE fslib_open_cache_hits counter
--fslib_open_cache_hits{fstype="cachefs"} 0
100 242075 100 242075 0 0 38747k # HELP fslib_file_replicate_count How many files are replicated.
# TYPE fslib_file_replicate_count counter
fslib_file_replicate_count 0
0# HELP fslib_file_replicate_fail_count How many files fail to replicate.
--:--:-# TYPE fslib_file_replicate_fail_count counter
-fslib_file_replicate_fail_count 0
# HELP fslib_fs_open_files Count how many files are opened by given filesystem
--# TYPE fslib_fs_open_files counter
:-fslib_fs_open_files{fstype="cachefs"} 0
-:# HELP fslib_fs_create_files Count how many files are created by given filesystem
--# TYPE fslib_fs_create_files counter
-fslib_fs_create_files{fstype="cachefs"} 0
-:--:--# HELP fslib_entry_stat Counter of fs stat calls
# TYPE fslib_entry_stat counter
3fslib_entry_stat{fstype="cachefs"} 0
9# HELP fslib_entry_exists Counter of fs exists calls
4# TYPE fslib_entry_exists counter
0fslib_entry_exists{fstype="cachefs"} 0
0k# HELP fslib_list_dir Counter of fs list directory calls
# TYPE fslib_list_dir counter
fslib_list_dir{fstype="cachefs"} 0
# HELP fslib_fs_delete_files Count how many files are deleted by given filesystem
# TYPE fslib_fs_delete_files counter
fslib_fs_delete_files{fstype="cachefs"} 0
# HELP fslib_open_cache_hits Count how many hits to cache file when opening a file for read.
# TYPE fslib_open_cache_hits counter
fslib_open_cache_hits{fstype="cachefs"} 0
# HELP fslib_open_cache_misses Count how many misses to cache file when opening a file for read.
# TYPE fslib_open_cache_misses counter
fslib_open_cache_misses{fstype="cachefs"} 0
# HELP fslib_star_cache_exist_calls Count how many times of the exist api has been called.
# TYPE fslib_star_cache_exist_calls counter
fslib_star_cache_exist_calls{fstype="cachefs"} 0
# HELP fslib_active_replicate_file_handle_count How many files are being replicated.
# TYPE fslib_active_replicate_file_handle_count gauge
fslib_active_replicate_file_handle_count 0
# HELP fslib_cache_threadpool_size Count CacheManager threadpool threads
# TYPE fslib_cache_threadpool_size gauge
fslib_cache_threadpool_size{fstype="cachefs"} 16
# HELP fslib_async_file_replicate_wait_count How many file are waiting to be replicated.
# TYPE fslib_async_file_replicate_wait_count gauge
fslib_async_file_replicate_wait_count 0
# HELP fslib_async_file_wait_timeout_count How many async files wait for too long before execution.
# TYPE fslib_async_file_wait_timeout_count gauge
fslib_async_file_wait_timeout_count 0
# HELP fslib_fs_instance_count Count how many filesystem instances still alive
# TYPE fslib_fs_instance_count gauge
fslib_fs_instance_count 0
# HELP fslib_hdfs_jni_queue_len How many tasks are pending in the hdfs jni queue.
# TYPE fslib_hdfs_jni_queue_len gauge
fslib_hdfs_jni_queue_len 0
# HELP fslib_star_cache_memory_size How many memory bytes does star cache occupy. unit: B
# TYPE fslib_star_cache_memory_size gauge
fslib_star_cache_memory_size{fstype="cachefs"} 0
# HELP fslib_star_cache_meta_memory_size How many memory bytes does star cache's meta occupy. unit: B
# TYPE fslib_star_cache_meta_memory_size gauge
fslib_star_cache_meta_memory_size{fstype="cachefs"} 0
# HELP fslib_star_cache_disk_size How many disk bytes does star cache occupy. unit: B
# TYPE fslib_star_cache_disk_size gauge
fslib_star_cache_disk_size{fstype="cachefs"} 0
# HELP fslib_write_io_size Histogram of write io size, unit: bytes
# TYPE fslib_write_io_size histogram
fslib_write_io_size_count{fstype="cachefs"} 0
fslib_write_io_size_sum{fstype="cachefs"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="8192"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="16384"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="32768"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="65536"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="131072"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="262144"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="1048576"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="4194304"} 0
fslib_write_io_size_bucket{fstype="cachefs",le="+Inf"} 0
fslib_write_io_size_count{fstype="srposix"} 54490539526
fslib_write_io_size_sum{fstype="srposix"} 281895089487312
fslib_write_io_size_bucket{fstype="srposix",le="+Inf"} 54490539526
# HELP fslib_write_io_latency Histogram of write io latency, unit: microsecond
# TYPE fslib_write_io_latency histogram
fslib_write_io_latency_count{fstype="cachefs"} 0
fslib_write_io_latency_sum{fstype="cachefs"} 0
fslib_write_io_latency_bucket{fstype="cachefs",le="200"} 0
fslib_write_io_latency_bucket{fstype="cachefs",le="400"} 0
fslib_write_io_latency_bucket{fstype="cachefs",le="800"} 0
fslib_write_io_latency_bucket{fstype="cachefs",le="1600"} 0
fslib_write_io_latency_bucket{fstype="cachefs",le="3200"} 0
fslib_write_io_latency_bucket{fstype="cachefs",le="6400"} 0
fslib_write_io_latency_bucket{fstype="cachefs",le="12800"} 0
fslib_write_io_latency_bucket{fstype="cachefs",le="+Inf"} 0
fslib_write_io_latency_count{fstype="srposix"} 54490539526
fslib_write_io_latency_sum{fstype="srposix"} 340236322170.676
fslib_write_io_latency_bucket{fstype="srposix",le="+Inf"} 54490539526
# HELP fslib_read_io_size Histogram of read io size, unit: bytes
# TYPE fslib_read_io_size histogram
fslib_read_io_size_count{fstype="cachefs"} 0
fslib_read_io_size_sum{fstype="cachefs"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="8192"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="16384"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="32768"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="65536"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="131072"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="262144"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="1048576"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="4194304"} 0
fslib_read_io_size_bucket{fstype="cachefs",le="+Inf"} 0
fslib_read_io_size_count{fstype="srposix"} 142472457862
fslib_read_io_size_sum{fstype="srposix"} 997820557591628
fslib_read_io_size_bucket{fstype="srposix",le="+Inf"} 142472457862
# HELP fslib_read_io_latency Histogram of read io latency, unit: microsecond
# TYPE fslib_read_io_latency histogram
fslib_read_io_latency_count{fstype="cachefs"} 0
fslib_read_io_latency_sum{fstype="cachefs"} 0
fslib_read_io_latency_bucket{fstype="cachefs",le="200"} 0
fslib_read_io_latency_bucket{fstype="cachefs",le="400"} 0
fslib_read_io_latency_bucket{fstype="cachefs",le="800"} 0
fslib_read_io_latency_bucket{fstype="cachefs",le="1600"} 0
fslib_read_io_latency_bucket{fstype="cachefs",le="3200"} 0
fslib_read_io_latency_bucket{fstype="cachefs",le="6400"} 0
fslib_read_io_latency_bucket{fstype="cachefs",le="12800"} 0
fslib_read_io_latency_bucket{fstype="cachefs",le="+Inf"} 0
fslib_read_io_latency_count{fstype="srposix"} 142472457862
fslib_read_io_latency_sum{fstype="srposix"} 3633366540219.043
fslib_read_io_latency_bucket{fstype="srposix",le="+Inf"} 142472457862
# HELP fslib_close_io_latency Histogram of close io latency, unit: microsecond
# TYPE fslib_close_io_latency histogram
fslib_close_io_latency_count{fstype="cachefs"} 0
fslib_close_io_latency_sum{fstype="cachefs"} 0
fslib_close_io_latency_bucket{fstype="cachefs",le="200"} 0
fslib_close_io_latency_bucket{fstype="cachefs",le="400"} 0
fslib_close_io_latency_bucket{fstype="cachefs",le="800"} 0
fslib_close_io_latency_bucket{fstype="cachefs",le="1600"} 0
fslib_close_io_latency_bucket{fstype="cachefs",le="3200"} 0
fslib_close_io_latency_bucket{fstype="cachefs",le="6400"} 0
fslib_close_io_latency_bucket{fstype="cachefs",le="12800"} 0
fslib_close_io_latency_bucket{fstype="cachefs",le="+Inf"} 0Rocky
06/08/2026, 3:21 PMdefault_cache_ or fslib_ prefixes.
Here is the mapping for the metrics you were missing:
1. Block Cache Hit Bytes
* What you looked for: starrocks_be_block_cache_hit_bytes
* What you have: default_cache_hit_bytes
* Note: The name "default" refers to the default cache instance. If this is 0, it means your queries are currently not hitting the local NVMe disk cache (they might be hitting the in-memory Page Cache instead, which your output shows is very active: starrocks_be_page_cache_hit_count).
2. Read Throughput
* What you looked for: starrocks_be_fslib_read_throughput
* What you have: fslib_read_io_size_sum
* How to use it: This is a cumulative counter. To get the throughput (bytes/sec) in Grafana, use the irate or rate function:
promql
irate(fslib_read_io_size_sum[1m])
* Labels matter:
* `fstype="srposix"`: In your output, this has a very high value (997 TB total). This represents reads from the local filesystem (the NVMe disks used for cache).
* `fstype="cachefs"`: This represents the logic layer of the Data Cache. If this is 0, your Data Cache might not be fully initialized or utilized for the current workload.
3. Other Important Mappings from your output:
Concept | Metric in your output
Cache Misses | fslib_open_cache_misses{fstype="cachefs"}
Cache Latency | fslib_read_io_latency_sum / fslib_read_io_latency_count
Delete Vector Hits | lake_delvec_cache_hit_minute
Metadata Hits | lake_metadata_cache_hit_minute
Why are your cachefs metrics 0?
In your snippet, fslib_read_io_size_sum{fstype="srposix"} is huge, but fstype="cachefs" is 0. This usually happens if:
1. Version behavior: In some versions, StarRocks reports all local cache I/O under the srposix type because the cache is stored on a POSIX-compliant local disk.
2. Page Cache Dominance: Your starrocks_be_page_cache_hit_count is extremely high (151 billion). This suggests your "hot" data fits in the BE's memory (RAM), so StarRocks is serving queries from RAM (Page Cache) before it ever needs to look at the NVMe disk (Data Cache).
Recommendation
For a high-throughput PK table, you should specifically watch:
1. lake_delvec_cache_hit_minute: If this is 0 or low while lake_delvec_cache_miss (if visible) is high, your upsert performance will drop significantly.
2. irate(fslib_read_io_size_sum{fstype="srposix"}[1m]): Use this to monitor the actual disk I/O throughput on your CN nodes.
References
• administration/management/monitoring/metrics-shared-data.md
• data_source/data_cache_observe.md
• using_starrocks/caching/block_cache.md
• administration/management/monitoring/metrics.md
References
• data_source/data_cache_observe.md
• administration/management/monitoring/metrics-shared-data.md
• using_starrocks/caching/block_cache.md
• administration/management/monitoring/metrics.md
References
• administration/management/monitoring/metrics.mdRocky
06/08/2026, 3:21 PMMinn Fong
06/08/2026, 3:25 PMRocky
06/08/2026, 3:25 PMfstype labels within the fslib_ metrics.
Based on your specific metric output, here are the exact names and labels to use:
1. S3/Remote Lookup (The "Miss")
When StarRocks cannot find data locally, it fetches it from S3. These metrics will increment:
* Metric: fslib_read_io_size_sum{fstype="s3"} (or oss, ks3, hdfs depending on your storage).
* Logic: If you see throughput on this metric, your cluster is actively pulling data from the remote bucket.
* Latency: fslib_read_io_latency_sum{fstype="s3"} / fslib_read_io_latency_count{fstype="s3"} will show you the actual S3 network latency.
2. Local Disk Cache Hit (The "Disk Hit")
If the data was already downloaded and is being read from the local NVMe cache:
* Metric: fslib_read_io_size_sum{fstype="srposix"}
* Logic: In your output, this has a very high value (997 TB). This indicates the BE is reading data from the local disks where the storage_root_path (cache) is mounted.
* Alternative: default_cache_hit_bytes (This is the logical counter for the Block Cache engine).
3. Memory Cache Hit (The "RAM Hit")
StarRocks has an additional layer of in-memory cache (Page Cache) that sits above the disk cache:
* Metric: starrocks_be_page_cache_hit_count
* Logic: Your output shows 151 billion hits here. This means the vast majority of your queries are being served directly from RAM, which is why your S3/Remote metrics might currently be 0.
──────────
Summary Table for Grafana
Source | Metric Name + Label | Meaning
RAM Hit | starrocks_be_page_cache_hit_count | Served from BE memory (fastest).
Disk Hit | fslib_read_io_size_sum{fstype="srposix"} | Served from local NVMe cache (fast).
S3 Lookup | fslib_read_io_size_sum{fstype="s3"} | Served from Remote Object Storage (slowest).
Troubleshooting "0" Values
In your provided text, fslib_read_io_size_sum{fstype="cachefs"} is 0. This is normal because cachefs is a virtual management layer. The actual data flow is recorded under srposix (reading the cached file from disk) or s3 (reading the file from the cloud).
If you don't see fstype="s3" at all in your metrics:
It means your BE has not performed a remote read since it last started. All queries are currently being satisfied by the Page Cache (RAM) or Data Cache (Disk). Perform a query on a very old/cold table to force an S3 lookup, and the fstype="s3" (or equivalent) label will appear.
References
• administration/management/monitoring/metrics-shared-data.md
• data_source/data_cache_observe.md
• faq/shared_data_faq.md
References
• data_source/feature-support-data-lake-analytics.md
• knowledge/usage/storage/hdfs_storage_volume_extended.md
• sql-reference/sql-functions/table-functions/files.md
• deployment/shared_data/feature-support-shared-data.mdMinn Fong
06/08/2026, 3:50 PMRocky
06/08/2026, 3:51 PMdatacache_disk_size to a non-zero value to enable NVMe caching in a shared-data cluster, but there is an important interaction between two settings you should know:
1. The Default "80%" Rule
In shared-data clusters (using CN nodes), StarRocks uses the greater of two values for the disk cache limit:
* `starlet_star_cache_disk_size_percent`: Default is 80 (80% of total disk).
* `datacache_disk_size`: Default is 0.
Because 80% is greater than 0, StarRocks will automatically use 80% of your disk space for the NVMe cache by default. You do not need to set datacache_disk_size unless you want to specify a fixed physical limit (e.g., 500G or 2T) instead of a percentage.
2. Does "0" mean RAM-only?
While the documentation for datacache_disk_size says a value of 0 means "only memory is used," this is often overridden in cloud-native/shared-data deployments by the starlet_star_cache_disk_size_percent parameter.
* If you leave both at default: You get 80% disk cache + a small amount of memory cache.
* If you want to use 100% of your NVMe: You should set starlet_star_cache_disk_size_percent = 90 (leaving some room for logs/OS) or set datacache_disk_size to your specific disk capacity (e.g., 1800G).
3. RAM vs. Disk Cache
StarRocks actually uses both:
* datacache_mem_size: Controls the Page Cache (RAM). This is usually small (default 0 or a low %).
* datacache_disk_size / starlet...percent: Controls the Block Cache (NVMe/SSD). This is where the bulk of your S3 data is cached.
Recommendation for CN Nodes
If you have dedicated NVMe disks for your CN nodes, it is best practice to:
1. Set the path: Ensure storage_root_path in your BE/CN config points to the mount point of your NVMe disk.
2. Adjust the limit: If you want to be explicit, set datacache_disk_size to roughly 90% of your NVMe size to ensure the system doesn't accidentally fill the disk 100% with logs or metadata.
_ _Example:* datacache_disk_size = 1800G (for a 2TB drive).
How to verify what is actually being used:
Run this SQL command in StarRocks to see the active configuration being used by the engine:
sql
SELECT * FROM information_schema.be_configs
WHERE NAME LIKE "%datacache_disk_size%"
OR NAME LIKE "%starlet_star_cache_disk_size_percent%";
References
• administration/management/BE_configuration.md
• using_starrocks/caching/block_cache.md
• deployment/shared_data/feature-support-shared-data.md
• data_source/data_cache.md
References
• administration/management/BE_configuration.md
• using_starrocks/caching/block_cache.md
• deployment/shared_data/feature-support-shared-data.md
• data_source/data_cache_observe.mdMinn Fong
06/08/2026, 3:53 PM# StarRocks Backend Node Configuration for Stats
# Based on <https://docs.starrocks.io/docs/cover_pages/shared_nothing_deployment/>
JAVA_OPTS="-Dlog4j2.formatMsgNoLookups=true -Xmx8192m -XX:+UseG1GC -XX:ErrorFile=${LOG_DIR}/hs_err_pid%p.log -Djava.security.policy=${STARROCKS_HOME}/conf/udf_security.policy --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/sun.nio.cs=ALL-UNNAMED --add-opens=java.base/sun.security.action=ALL-UNNAMED --add-opens=java.base/sun.util.calendar=ALL-UNNAMED --add-exports=java.base/sun.nio.ch=ALL-UNNAMED"
# Network configurations
be_port = 9060
heartbeat_service_port = 9050
brpc_port = 8060
# Backend node service configurations
be_host = 0.0.0.0
priority_networks = 172.30.0.0/16
# Storage configurations
storage_root_path = /mnt/starrocks/data1/be/storage;/mnt/starrocks/data2/be/storage;/mnt/starrocks/data3/be/storage;/mnt/starrocks/data4/be/storage
# Log configurations
sys_log_level = INFO
# Memory configurations
mem_limit = 95%
# Data Lake cache (accelerates reads from Iceberg via External Catalog)
# datacache_enable = true
# datacache_disk_size = 1610612736000
# datacache_meta_path = /mnt/starrocks/be/datacache/meta
# Page cache configurations
storage_page_cache_limit = 20%
disable_storage_page_cache = false
# Compaction configurations
base_compaction_num_threads_per_disk = 2
cumulative_compaction_num_threads_per_disk = 2
# Streaming load configurations
streaming_load_max_batch_size_mb = 2048
streaming_load_max_mb = 102400
# Reduce flushes (512 MB) => Reduce disk I/O
write_buffer_size = 536870912
# Wide-table optimization (512 MB) => Reduce RPC call frequency to BE
max_tablet_write_chunk_bytes = 536870912
# Parallelize the PK index "Apply" phase for your 16-core nodes
update_compaction_num_threads_per_disk = 4
enable_prefetch = true
# Routine Load configurations (Kafka ingestion)
max_consumer_num_per_group = 5
# Security configurations
enable_token_check = true
# Transaction configurations
max_runnings_transactions_per_txn_map = 100
# Allow each tablet to run compaction more frequently (default 120)
update_compaction_per_tablet_min_interval_seconds=30
# BE checks tablet for compaction more frequently
update_compaction_check_interval_seconds=10
# PKI index compaction parallelism (default 1)
pindex_major_compaction_limit_per_disk=4
# Limits each compaction task to 100 rowsets
max_cumulative_compaction_num_singleton_deltas=100
# Delete trash directory after 1 hour
trash_file_expire_time_sec=3600
# More compaction concurrency
compact_threads=12
These are the current configurations that make my shared nothing cluster sustainable for ingestion throughput. Give me list of shared data configurations important to tune in the conf fileRocky
06/08/2026, 3:53 PMstorage_root_path is no longer for permanent data but for the Data Cache.
* starlet_use_star_cache = true: Enables the modern block-level Data Cache (default true in v3.2.3+).
* starlet_star_cache_disk_size_percent = 90: Since your disks are now just cache, you can safely increase this from the default 80% to 90% to maximize NVMe utilization.
* datacache_disk_size = 0: Keep at 0 to let the percentage setting above control the logic, or set to a specific byte value (e.g., 1610612736000 for 1.5TB) if you want a hard limit.
* datacache_mem_size: You can allocate a portion of RAM (e.g., 10G or 5%) to cache hot metadata and small blocks in memory for sub-millisecond response.
2. Shared-Data Compaction (High Ingestion Support)
Compaction in shared data pulls data from S3, merges it, and pushes it back.
* compact_threads: In shared data, it is recommended to set this to 25% of your CPU cores. For your 16-core nodes, set this to 4. (Your current 12 might cause S3 throttling or OOM during high ingestion).
* max_cumulative_compaction_num_singleton_deltas = 100: (Recommended) Reducing this from the default (500/1000) makes each compaction task smaller and faster, which is better for the remote I/O nature of shared data.
* lake_compaction_stream_buffer_size_bytes = 4194304: Increase this (e.g., to 4MB) to provide a larger buffer for reading data from S3 during compaction. This significantly accelerates the merge process.
* lake_pk_compaction_max_input_rowsets = 500: Specifically for PK tables, this limits the number of files merged at once to prevent long-running tasks.
3. Primary Key Table Optimizations
Since your cluster is for high-throughput PK ingestion:
* enable_pk_index_parallel_compaction = true: Ensures the "Apply" phase of your PK index remains parallel in the cloud-native engine.
* lake_enable_ingest_slowdown = true: (FE Side) This is the "backpressure" setting. If compaction falls too far behind (S3 latency/bottleneck), it will slow down ingestion rather than letting the system crash or become unreadable.
* lake_compaction_score_upper_bound = 2000: (FE Side) Sets the limit for the slowdown above.
4. S3 / Object Storage Stability
* lake_service_max_retry_count = 10: Increase retries for S3 operations to handle transient cloud provider "SlowDown" or network errors during heavy ingestion.
* lake_s3_upload_part_size = 33554432: (32MB) Increasing the part size can improve throughput for large segment uploads to S3, though it uses more memory per thread.
Summary of what to change in your `be.conf`:
properties
# Network
starlet_port = 9070
# Storage (Now used as Cache)
storage_root_path = /mnt/starrocks/data1/be/storage;/mnt/starrocks/data2/be/storage...
# Data Cache
starlet_use_star_cache = true
starlet_star_cache_disk_size_percent = 90
# Shared-Data Compaction
compact_threads = 4
max_cumulative_compaction_num_singleton_deltas = 100
lake_compaction_stream_buffer_size_bytes = 4194304
lake_pk_compaction_max_input_rowsets = 500
enable_pk_index_parallel_compaction = true
# Object Storage Stability
lake_service_max_retry_count = 10
Note: In shared-data mode, you should also check your FE configurations. Parameters like lake_compaction_max_tasks (set to -1 for adaptive) are now managed globally by the FE to prevent BEs from overloading the object store.
References
• administration/management/BE_configuration.mdRocky
06/08/2026, 3:53 PMMinn Fong
06/08/2026, 6:31 PMsum(rate(fslib_open_cache_hits[$interval])) / (sum(rate(fslib_open_cache_hits[$interval])) + sum(rate(fslib_open_cache_misses[$interval]))) shows different values than sum(rate(fslib_read_io_size_sum{fstype="srposix"}[$interval])) / sum(rate(fslib_read_io_size_sum[$interval])) * 100Rocky
06/08/2026, 6:31 PMfslib_open_cache_hits): This is a Count-based metric. It measures the frequency of file handle lookups. When StarRocks needs to read a file (e.g., a segment file), it first checks if it already has an open file handle in its internal cache.
_ _Unit:* Operations (Hits / Total Opens).
_ _Meaning:* High values here mean the system is effectively reusing file metadata and handles, reducing the overhead of repeated "open" syscalls.
* Query 2 (fslib_read_io_size_sum): This is a Volume-based metric. It measures the total number of bytes read.
_ _Unit:* Bytes (Bytes from local disk / Total Bytes read).
_ _Meaning:* This is your actual Data Cache Hit Rate. It tells you how much of your actual query data volume was served from the local NVMe (srposix) versus being pulled from S3.
2. The "Small File" vs. "Large Scan" Discrepancy
Because one is based on frequency and the other on size, they rarely match:
* Scenario A: You open 1,000 small metadata files (1KB each). You hit the "open cache" for all 1,000. Your Open Hit Rate is 100%. But then you read one massive 1GB data block from S3 because it wasn't in the data cache. Your Data Hit Rate (by size) would be near 0%.
* Scenario B: You miss the "open cache" on a single large file (one miss), but then you read 10GB of data from that file entirely from the local NVMe cache. Your Open Hit Rate is 0%, but your Data Hit Rate is 100%.
3. Metric Definitions
Metric Component | What it represents
fslib_open_cache_... | Hits/Misses in the File Handle Cache. It caches the fd (file descriptor) and basic metadata of files to avoid slow OS-level or S3-level "open" calls.
fslib_read_io_size_sum{fstype="srposix"} | Data served from local storage (the Data/Block Cache). In shared-data mode, srposix refers to the POSIX filesystem on your local NVMe.
fslib_read_io_size_sum (total) | The sum of all read IO, including srposix (local cache) and `s3`/`oss`/`ks3` (remote storage).
Which one should you use?
* If you want to know "Is my cache saving me money and making queries fast?", use the Byte-based query (Query 2). This represents the actual offloading of S3 traffic.
* If you are troubleshooting high CPU system time or metadata latency, look at the Open Cache query (Query 1).
Recommendation: For performance tuning and "Cache Hit Rate" in the traditional sense, stick to the Byte-based calculation:
sum(rate(fslib_read_io_size_sum{fstype="srposix"}[$interval])) / sum(rate(fslib_read_io_size_sum[$interval]))
[$interval]))`
References
• data_source/data_cache.md
• data_source/data_cache_observe.md
• data_source/data_cache_troubleshooting.md
• using_starrocks/caching/block_cache.mdMinn Fong
06/08/2026, 6:38 PMRocky
06/08/2026, 6:38 PMstarrocks_fe_tablet_max_compaction_score | FE | The highest compaction score across all tablets. Critical: If this exceeds 100, ingestion slows down; if it hits 2000, ingestion is rejected.
starrocks_be_lake_compaction_max_score | BE | The maximum score calculated by the Lake engine on that specific node.
starrocks_be_compact_threads | BE | Number of active threads performing compaction. Compare this against your compact_threads limit.
starrocks_be_lake_compaction_count | BE | Total number of compaction tasks completed by this node.
2. Update & Apply Latency (Primary Key Tables)
For Primary Key tables, "Apply" is the phase where the system updates the index and deletes old versions. This is usually the bottleneck for update latency.
Metric | Level | Description
starrocks_be_update_rowset_commit_apply_duration_us | BE | The time spent on the APPLY phase. This is the best proxy for "Update Latency" in PK tables.
starrocks_be_update_apply_queue_count | BE | The number of transactions waiting to be "Applied." If this grows, your data visibility (freshness) will lag.
starrocks_be_update_primary_index_num | BE | Number of PK indexes loaded in memory. If this drops, it means indexes are being evicted, causing "Index Reload" latency.
3. Transaction Publish Latency
"Publishing" is the final step of a load (Stream Load, Routine Load, etc.) that makes the data visible to queries.
Metric | Level | Description
starrocks_fe_txn_publish_latency_ms | FE | Total end-to-end time from transaction commit to visibility.
starrocks_fe_txn_publish_schedule_latency_ms | FE | Time the transaction spent waiting in the queue for a publish thread. High values mean the FE is overloaded or publish_version_worker_count is too low.
starrocks_fe_txn_publish_execute_latency_ms | FE | The active time spent sending publish RPCs to the BE nodes.
4. Shared Data Specifics (Starlet/S3)
Since shared data relies on S3, monitor for "SlowDown" errors or high latency:
Metric | Level | Description
starrocks_be_fslib_read_io_latency | BE | Average/Quantile latency for reading from S3. Useful for identifying S3 throttling.
starrocks_be_lake_get_tablet_metadata_latency_ms | BE | Latency for fetching tablet metadata from the shared store.
Pro-tip: You can view these live in StarRocks without Prometheus using these SQL commands:
* SHOW PROC '/compactions' (Compaction history and status)
* SHOW PROC '/transactions' (Active/Recent transaction details)
_ SELECT _ FROM information_schema.be_compactions (Current node-level compaction health)
References
• administration/management/monitoring/metrics-shared-data.md
• administration/management/monitoring/metrics.md
• administration/management/compaction.md
• data_source/data_cache_observe.md
References
• administration/management/monitoring/metrics.mdMinn Fong
06/08/2026, 6:47 PMRocky
06/08/2026, 6:48 PMstarrocks_monitor) and click Import.
Note: If you are using an older version of StarRocks (pre-v3.0), you may need to check the official documentation for legacy-compatible templates.
References
• administration/management/monitoring/Monitor_and_Alert.md
• administration/management/monitoring/metrics-shared-data.md
• quick_start/shared-data.md
References
• administration/management/monitoring/Monitor_and_Alert.md
• quick_start/shared-data.md
• deployment/shared_data/minio.md
• administration/management/monitoring/metrics-shared-data.md
• deployment/shared_data/gcs.md
• deployment/shared_data/s3.mdMinn Fong
06/08/2026, 8:00 PMRocky
06/08/2026, 8:00 PMstarrocks_be_tablet_update_max_compaction_score is not applicable to shared-data (cloud-native) clusters. It is designed for the shared-nothing (classic) architecture where each BE manages its own local Primary Key index and compaction lifecycle.
In a shared-data cluster, you should use the following metrics instead:
1. The Correct Shared-Data Metric: FE Side
In shared-data mode, the FE Leader is responsible for calculating and tracking compaction scores because the data and metadata are stored centrally (e.g., in S3).
* Metric: starrocks_fe_tablet_max_compaction_score
* What to watch: This is the primary indicator of compaction health. If this value exceeds 100, the cluster is falling behind. If it reaches 2000, ingestion will be rejected for that partition.
2. Why the "BE" metric doesn't work for Shared-Data
* Statelessness: Compute Nodes (CNs) in shared-data are stateless. They do not maintain a permanent local state of all tablets. They only perform compaction tasks when explicitly instructed by the FE.
* Architecture: The metric you mentioned (tablet_update_max_compaction_score) pulls data from the local TabletManager. In shared-data, the storage engine is the Lake Engine, which uses different internal structures.
* Result: On a shared-data CN/BE, this metric will typically return 0 or no data, as there are no "classic" tablets managed locally.
3. Alternative "Lake" Metrics (BE/CN Side)
If you want to monitor the status of compaction on the execution nodes (CN/BE), look for metrics with the lake_ prefix:
* starrocks_be_lake_compaction_count: Total compaction tasks completed.
* starrocks_be_lake_compaction_max_score: The highest score among tablets currently being compacted on that node.
* starrocks_be_lake_pk_compaction_duration_us: Time spent on Primary Key compaction specifically in the shared-data engine.
Summary for Monitoring
If you are setting up alerts for shared-data compaction:
* Alert on: starrocks_fe_tablet_max_compaction_score > 100
* Verify with SQL: SHOW PROC '/compactions' or SELECT * FROM information_schema.partitions_meta ORDER BY MAX_CS DESC;
References
• administration/management/monitoring/metrics.md
• administration/management/compaction.md
• administration/management/monitoring/metrics-shared-data.md
• sql-reference/information_schema/be_compactions.md
References
• administration/management/compaction.md
• administration/management/monitoring/metrics.md
• sql-reference/information_schema/be_compactions.md
• administration/management/FE_configuration.mdMinn Fong
06/08/2026, 8:07 PMRocky
06/08/2026, 8:08 PMstarrocks_be_datacache_disk_used_bytes | BE | Actual amount of NVMe space consumed by the cache.
starrocks_be_datacache_disk_quota_bytes | BE | The total capacity allocated for the cache on the NVMe drive.
starrocks_be_fslib_star_cache_data_disk_size | BE | (Internal) Actual disk usage of the Starlet engine cache.
starrocks_be_block_cache_disk_used_rate | BE | Percentage of cache disk used (Used / Quota).
2. If using NVMe for Local Data Storage (Shared-Nothing Cluster)
If you have a classic cluster where data is stored permanently on NVMe, use these system-level disk metrics:
Metric | Level | Description
starrocks_be_disks_total_capacity | BE | Total capacity of the disk volume where StarRocks data is stored.
starrocks_be_disks_avail_capacity | BE | Available (free) space on the disk.
starrocks_be_disks_data_used_capacity | BE | Space specifically occupied by StarRocks data files.
3. Recommended Alerting (PromQL)
To prevent the node from running out of space or the cache from becoming inefficient, you can set up these alerts:
* Low Disk Space (Shared-Nothing):
promql
(starrocks_be_disks_avail_capacity / starrocks_be_disks_total_capacity) * 100 < 20
Triggers when free space is below 20%.
* Cache Utilization (Shared-Data):
promql
(starrocks_be_datacache_disk_used_bytes / starrocks_be_datacache_disk_quota_bytes) * 100 > 95
Note: In shared-data, the cache is designed to stay nearly full (LRU eviction). High usage is normal, but a sudden drop might indicate disk issues.
Pro-Tip: If your NVMe is managed as part of a Kubernetes PV or a host filesystem, you can also use node_exporter metrics like node_filesystem_avail_bytes for a hardware-level view of the mount point.
References
• administration/management/monitoring/metrics.md
• using_starrocks/caching/block_cache.md
• administration/management/monitoring/alert.md
• data_source/data_cache_observe.md
References
• administration/management/monitoring/Monitor_and_Alert.md
• administration/management/monitoring/metrics.md
• administration/management/BE_configuration.md
• administration/management/monitoring/alert.md