Shiv Kumar
08/07/2026, 9:58 AMRocky
08/07/2026, 9:58 AMr6id or r7iz
* Family: r6id (Intel Ice Lake) or r7iz (High Frequency Intel).
* Why: These offer a large memory-to-CPU ratio (8:1), which is critical for Cube.js workloads that involve complex joins and high concurrency. The d suffix indicates local NVMe SSDs, which are essential for the Data Cache.
* Best Price/Performance: c6id or m6id
* Family: c6id (Compute-optimized) or m6id (General purpose).
* Why: c6id is great for CPU-bound complex joins. Use m6id if you need a more balanced memory profile. Both include local NVMe.
* Storage Optimized (Extreme Cache Capacity): i3en or i4i
* Family: i4i (Intel-based).
* Why: These provide massive local NVMe throughput and capacity. Ideal if your "hot" Iceberg dataset is very large and you want to avoid hitting S3 frequently.
Note on Architecture: While StarRocks supports Graviton (e.g.,2. FE Nodes (Frontend) FEs handle metadata and query planning. For Iceberg, FEs also manage the Glue catalog metadata. * Recommended:), StarRocks is heavily optimized for AVX2/AVX-512 instruction sets on x86 (Intel/AMD) to "fully unleash" its vectorized execution engine. For the absolute lowest latency on complex joins, Intel-based instances (r7gd,i, oridsuffixes) are currently recommended.iz
c6i.2xlarge or c7i.2xlarge.
* Why: FE is not storage-intensive but benefits from fast single-core performance for planning complex queries. 8 vCPUs and 16-32GB RAM is usually sufficient.
──────────
Key Configurations for Iceberg + Glue
To meet your low-latency/high-concurrency goals, ensure the following are configured in your Helm values or StarRocks cluster:
1. Enable Data Cache: This is the most important setting for external tables.
* BE/CN Config: datacache_enable = true
* Point storage_root_path to your local NVMe mount point (e.g., /mnt/nvme/).
2. Glue Metadata Caching:
* StarRocks caches Glue metadata in the FE to avoid repeated API calls.
* Ensure enable_iceberg_metadata_cache = true (default in v3.3+).
* For very large Iceberg tables, enable Distributed Metadata Planning (available in v3.3+) to distribute the metadata parsing load across BEs.
3. Concurrency Tuning:
* Increase query_parallelism and pipeline_dop if your instances have many cores (e.g., 32+).
* Cube.js often generates many small concurrent queries; ensure your FE has enough report_queue_size to handle the scheduling.
Summary Table
Role | Recommended Family | Key Requirement
BE / CN | r6id / i4i | Local NVMe for Data Cache; High RAM for joins.
FE | c6i | Compute-optimized for query planning.
Disk | Local NVMe | Avoid EBS for the datacache path to keep latency low.
References
• data_source/data_cache.md
• using_starrocks/caching/block_cache.md
• data_source/data_cache_troubleshooting.mdShiv Kumar
08/07/2026, 10:02 AMRocky
08/07/2026, 10:02 AMd suffix):
* Best for Memory-Intensive Joins: r7gd or r6gd
* Recommendation: r7gd.2xlarge or larger.
* Why: These are Graviton3/Graviton2 instances with local NVMe. The 8:1 RAM-to-vCPU ratio is perfect for the complex joins and high concurrency generated by Cube.js.
* Best for Storage-Heavy Caching: is4gen or im4gn
* Why: These use the AWS Nitro SSDs and are specifically designed for workloads that need massive local storage for caching. If your Iceberg "hot" dataset is very large, these offer the best throughput for the Data Cache.
Important Deployment Notes
* Version Requirement: Ensure you are using StarRocks v3.3.0 or later to benefit from the ARM optimizations.
* Data Cache Setup: Even on Graviton, you must explicitly enable the cache. Set datacache_enable = true and point your storage_root_path to the mounted local NVMe drive on your EKS nodes.
* Image Architecture: When deploying via Helm, ensure you are pulling the arm64 version of the StarRocks image.
Summary: For a modern StarRocks deployment on EKS querying Iceberg, r7gd is arguably the best choice for balancing cost, complex join performance, and the low latency provided by local NVMe caching.
References
• deployment/shared_data/feature-support-shared-data.md
• using_starrocks/caching/block_cache.md
• data_source/data_cache.md
• faq/Deploy_faq.mdShiv Kumar
08/07/2026, 10:14 AMd instances. How much impact in performance will it have?Rocky
08/07/2026, 10:14 AMd instances) for a StarRocks Data Cache is significant, particularly for high-concurrency workloads like Cube.js.
While gp3 is excellent for persistent storage, using it for a "hot" Data Cache often becomes a performance bottleneck compared to local NVMe.
1. Fundamental Difference: Network vs. Bus
* gp3 (EBS): This is network-attached storage. Every read/write request must travel over the AWS internal network. Even with "EBS-optimized" instances, you are subject to network overhead and potential congestion.
* Local NVMe (d instances): These are physically attached to the host server. Data travels over the PCIe bus, which is orders of magnitude faster and has lower latency than any network-based storage.
2. Latency Impact (The "Feel" of the Query)
For StarRocks' Data Cache, random read latency is the most critical metric.
* gp3 Latency: Usually in the single-digit milliseconds (1ms–5ms).
* Local NVMe Latency: Usually in the microseconds (sub-0.1ms).
* Impact: When a complex join needs to pull thousands of blocks from the cache, the difference between 2ms and 100μs adds up. On local NVMe, cache hits feel "instant" (like memory), whereas on gp3, they feel like "fast disk."
3. IOPS and Throughput (High Concurrency)
High concurrency from Cube.js means many simultaneous requests to the cache.
* gp3 Limits: A standard gp3 volume starts at 3,000 IOPS and 125 MB/s throughput. You can pay to increase this (up to 16,000 IOPS), but it is a hard cap.
* Local NVMe Performance: A single local NVMe drive on an r6id or r7gd instance can easily deliver hundreds of thousands of IOPS and GBs per second of throughput without additional cost.
* Impact: Under high concurrency, gp3 volumes can experience "I/O wait" or throttling, causing query latency to spike. Local NVMe handles high-parallelism vectorized reads without breaking a sweat.
4. Cost vs. Durability
* Durability: gp3 is durable (persists if the node dies). Local NVMe is ephemeral (data is lost if the instance is terminated).
* Why it doesn't matter for Cache: Because this is a Data Cache, not the primary storage. If a node restarts and the local NVMe is wiped, StarRocks simply re-fetches the "hot" data from S3/Iceberg. You lose a few minutes of "warm-up" time, but you gain massive permanent performance.
Summary Comparison Table
Feature | EBS (gp3) | Local NVMe (d instances)
Random Read Latency | ~1–5 ms (High) | < 0.1 ms (Ultra Low)
Max Throughput | Up to 1,000 MB/s (Paid) | 2,000+ MB/s (Included)
Max IOPS | Up to 16,000 (Paid) | 400,000+ (Included)
Cost | Extra monthly fee per GB/IOPS | Included in the instance price
Best For | Persistent Metadata / Logs | Data Cache / High-Speed Joins
Recommendation
If your goal is low latency and high concurrency for Iceberg:
1. Switch to d instances (like r7gd or r6id).
2. Mount the Local NVMe at a path like /mnt/nvme.
3. Configure StarRocks to use this path for storage_root_path.
Using gp3 for the Data Cache is essentially paying for network storage to cache data that is already on network storage (S3). Local NVMe breaks this "removes the network" from the equation for your hot data.
References
• data_source/data_cache.md
• using_starrocks/caching/block_cache.md
• data_source/data_cache_troubleshooting.md
References
• data_source/data_cache.md
• using_starrocks/caching/block_cache.md
• data_source/data_cache_troubleshooting.mdRocky
08/07/2026, 10:14 AMShiv Kumar
08/07/2026, 10:29 AMvalues.yaml for deployment update this for new deployment considering I am going with r6gd.2xlarge instances.
Also give me family suggestions for fe, be and cn instances separately
operator:
global:
rbac:
create: true
serviceAccount:
name: 'starrocks'
annotations:
<http://eks.amazonaws.com/role-arn|eks.amazonaws.com/role-arn>: 'arn:aws:iam::025778817848:role/starrocks-role'
timeZone: 'UTC'
starrocks:
starrocksCluster:
enabledBe: true
enabledCn: true
initPassword:
enabled: true
passwordSecret: starrocks-root-pass
starrocksFESpec:
replicas: 3
serviceAccount: 'starrocks'
service:
annotations:
<http://prometheus.io/path|prometheus.io/path>: "/metrics"
<http://prometheus.io/port|prometheus.io/port>: "8030"
<http://prometheus.io/scrape|prometheus.io/scrape>: "true"
resources:
requests:
cpu: 1
memory: 16Gi
limits:
cpu: 4
memory: 32Gi
storageSpec:
name: fe
storageClassName: 'gp3'
storageSize: 20Gi
logStorageSize: 5Gi
config: |
# Enable disk-based metadata caching for Iceberg
enable_iceberg_metadata_disk_cache = true
# Increase memory for metadata (Default 512MB)
iceberg_metadata_memory_cache_capacity = 2147483648
# Increase disk cache for metadata (Default 2GB)
iceberg_metadata_disk_cache_capacity = 10737418240
# Enable background refresh to keep Glue metadata warm
enable_background_refresh_connector_metadata = true
# 2GB for cache metadata/results
query_cache_capacity = 2147483648
starrocksBeSpec:
replicas: 3
serviceAccount: 'starrocks'
service:
annotations:
<http://prometheus.io/path|prometheus.io/path>: "/metrics"
<http://prometheus.io/port|prometheus.io/port>: "8040"
<http://prometheus.io/scrape|prometheus.io/scrape>: "true"
resources:
requests:
cpu: 2
memory: 16Gi
limits:
cpu: 8
memory: 32Gi
storageSpec:
name: be
storageClassName: 'gp3'
storageSize: 50Gi
logStorageSize: 5Gi
config: |
be_port = 9060
webserver_port = 8040
heartbeat_service_port = 9050
brpc_port = 8060
sys_log_level = INFO
datacache_enable = true
# % of the BE storage volume
datacache_disk_size = 70%
# also powers Parquet footer cache
datacache_mem_size = 3G
datacache_eviction_policy = slru
mem_limit = 90%
enable_spill = true
spill_local_storage_dir = ${STARROCKS_HOME}/spill
starrocksCnSpec:
replicas: 1
serviceAccount: 'starrocks'
autoScalingPolicy:
version: v2
minReplicas: 1
maxReplicas: 5
hpaPolicy:
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleUp:
stabilizationWindowSeconds: 30
policies:
- type: Pods
value: 2
periodSeconds: 30
scaleDown:
stabilizationWindowSeconds: 600COLD cache,
policies:
- type: Pods
value: 1
periodSeconds: 120
service:
annotations:
<http://prometheus.io/path|prometheus.io/path>: '/metrics'
<http://prometheus.io/port|prometheus.io/port>: '8040'
<http://prometheus.io/scrape|prometheus.io/scrape>: 'true'
resources:
requests:
cpu: 2
memory: 16Gi
limits:
cpu: 8
memory: 32Gi
storageSpec:
name: cn
storageClassName: 'gp3'
storageSize: 50Gi
logStorageSize: 5Gi
persistentVolumeClaimRetentionPolicy:
whenScaled: Delete
whenDeleted: Delete
config: |
be_port = 9060
webserver_port = 8040
heartbeat_service_port = 9050
brpc_port = 8060
sys_log_level = INFO
# Increase threads for internal communication
brpc_num_threads = 256
# Data Cache for external (Iceberg) tables — CN is the PRIMARY scan/cache tier
datacache_enable = true
datacache_disk_size = 80%
datacache_mem_size = 3G
datacache_eviction_policy = slru
# Enable and tune Query Cache (BE RAM)
query_cache_capacity = 2147483648
mem_limit = 90%
enable_spill = true
spill_local_storage_dir = ${STARROCKS_HOME}/spillRocky
08/07/2026, 10:29 AMr6gd.2xlarge (Graviton + NVMe) for your Iceberg/Cube.js workload, you need to adjust your resources, update the image architecture, and—most importantly—mount the local NVMe drive for the Data Cache.
1. Updated values.yaml for r6gd.2xlarge
This configuration assumes you have mounted the local NVMe SSD on your EKS worker nodes (typically at /mnt/nvme0n1 or similar).
yaml
starrocks:
starrocksCluster:
enabledBe: true
enabledCn: true
# Ensure you are using v3.3.0+ for ARM optimizations
starrocksFESpec:
replicas: 3
resources:
requests:
cpu: 4
memory: 16Gi
limits:
cpu: 7 # Leave 1 core for OS/Kube
memory: 28Gi # FE doesn't need the full 64GB, keep it lean
config: |
enable_iceberg_metadata_disk_cache = true
iceberg_metadata_memory_cache_capacity = 4294967296 # Increased to 4GB
iceberg_metadata_disk_cache_capacity = 21474836480 # Increased to 20GB
enable_background_refresh_connector_metadata = true
query_cache_capacity = 2147483648
starrocksBeSpec:
replicas: 3
resources:
requests:
cpu: 7
memory: 58Gi
limits:
cpu: 7
memory: 58Gi
# IMPORTANT: To use the NVMe, we must mount the host path
storageVolumes:
- name: be-data
storageClassName: gp3
storageSize: 50Gi
mountPath: /opt/starrocks/be/storage
- name: nvme-cache
hostPath:
path: /mnt/nvme0n1 # Change to your node's actual NVMe mount path
mountPath: /opt/starrocks/be/datacache
config: |
# Core performance
mem_limit = 90%
# Direct Data Cache to the local NVMe mount
datacache_enable = true
# storage_root_path handles both data and cache
storage_root_path = /opt/starrocks/be/storage;/opt/starrocks/be/datacache,capacity:400
datacache_disk_size = 400G
datacache_mem_size = 4G
datacache_eviction_policy = slru
starrocksCnSpec:
replicas: 1
resources:
requests:
cpu: 7
memory: 58Gi
limits:
cpu: 7
memory: 58Gi
storageVolumes:
- name: nvme-cache-cn
hostPath:
path: /mnt/nvme0n1
mountPath: /opt/starrocks/cn/datacache
config: |
mem_limit = 90%
# CN is stateless, so use the NVMe for the storage root
storage_root_path = /opt/starrocks/cn/datacache
datacache_enable = true
datacache_disk_size = 400G
datacache_mem_size = 4G
# Optimization for high-concurrency complex joins
brpc_num_threads = 256
pipeline_exec_thread_pool_thread_num = 8
2. EC2 Family Suggestions (Graviton Edition)
For the best price-performance on StarRocks v3.3+, use these families:
Role | Recommended Family | Reason
FE | c7g.2xlarge | Graviton3 has significantly better single-core performance than Graviton2, which speeds up complex query planning. FE doesn't need NVMe.
BE | r7gd.2xlarge | Use r for high RAM (8:1 ratio) to handle complex joins. The d is mandatory for local NVMe. Graviton3 (r7gd) is ~25% faster than r6gd.
CN | r7gd.2xlarge | Same as BE. CNs are the best place to leverage local NVMe since they can scale elastically without rebalancing persistent data.
Important Implementation Details
1. Image Architecture: The Helm chart will automatically pull the arm64 version of the StarRocks images if your nodes are labeled correctly. Ensure you are using an image tag like 3.3-latest or 3.4-latest.
2. NVMe Mounting: AWS d instances do not mount the NVMe drive by default. You must use a UserData script or a DaemonSet (like the eks-nvme-ssd-provisioner) to format the drive and mount it to /mnt/nvme0n1 before the StarRocks pods start.Rocky
08/07/2026, 10:29 AMr family over c? Your use case involves complex joins. StarRocks joins are memory-intensive (hash tables). The r family gives you 64GB vs the c family's 16GB for the same CPU count, preventing "Memory Limit Exceeded" errors during high concurrency.
References
• data_source/data_cache.md
• quick_start/helm.md
• using_starrocks/caching/block_cache.md
• administration/management/BE_configuration.md
• deployment/prepare_deployment_files.md
)
deployment/prepare_deployment_files.md)
References
• knowledge/usage/best-practice.md
• data_source/data_cache.md
• using_starrocks/caching/query_cache.md
• using_starrocks/caching/block_cache.md
• deployment/shared_data/feature-support-shared-data.mdShiv Kumar
08/07/2026, 10:50 AMstarrocks.starrocksBeSpec.storageVolumes config in the helm default values. Are you sure this is correct config. I am referencing this file here: github.com/StarRocks/starrocks-kubernetes-operator/blob/…/values.yaml
_And this doc here: docs.starrocks.io/docs/quick_start/helm_
All docs recommend persistent storage onlyRocky
08/07/2026, 10:50 AMstorageVolumes field I used in the previous example is an internal field of the StarRocks Operator CRD, but the Helm chart simplifies this by providing specific hostPaths and emptyDirs arrays in the values.yaml.
To use the local NVMe on an r6gd instance for the Data Cache, you should use the hostPaths configuration.
Updated values.yaml for r6gd.2xlarge
This version uses the correct Helm syntax. It assumes your EKS nodes mount the local NVMe at /mnt/nvme0n1.
yaml
starrocks:
starrocksCluster:
enabledBe: true
enabledCn: true
starrocksFESpec:
replicas: 3
resources:
requests:
cpu: 4
memory: 16Gi
limits:
cpu: 7
memory: 28Gi
storageSpec:
name: fe
storageClassName: 'gp3'
storageSize: 20Gi
config: |
enable_iceberg_metadata_disk_cache = true
iceberg_metadata_memory_cache_capacity = 4294967296
iceberg_metadata_disk_cache_capacity = 21474836480
enable_background_refresh_connector_metadata = true
starrocksBeSpec:
replicas: 3
resources:
requests:
cpu: 7 # Leaving 1 core for OS/Kube
memory: 58Gi # Leaving some RAM for OS overhead
limits:
cpu: 7
memory: 58Gi
storageSpec:
name: be
storageClassName: 'gp3'
storageSize: 50Gi
# CORRECT HELM SYNTAX FOR LOCAL NVMe
hostPaths:
- name: nvme-cache
hostPath:
path: /mnt/nvme0n1 # The path on your EKS worker node
mountPath: /opt/starrocks/be/datacache
config: |
# Point to both gp3 (for local data/spill) and NVMe (for cache)
# Syntax: path1;path2,capacity:GB
storage_root_path = /opt/starrocks/be/storage;/opt/starrocks/be/datacache,capacity:400
datacache_enable = true
datacache_disk_size = 400G
datacache_mem_size = 4G
mem_limit = 90%
starrocksCnSpec:
replicas: 1
resources:
requests:
cpu: 7
memory: 58Gi
limits:
cpu: 7
memory: 58Gi
# CNs are stateless, so they only need the NVMe for caching
hostPaths:
- name: nvme-cache-cn
hostPath:
path: /mnt/nvme0n1
mountPath: /opt/starrocks/cn/datacache
config: |
storage_root_path = /opt/starrocks/cn/datacache
datacache_enable = true
datacache_disk_size = 400G
datacache_mem_size = 4G
mem_limit = 90%
Instance Family Recommendations (Graviton)
For the best price-performance ratio on StarRocks v3.3+, use these combinations:
Component | Recommended Family | Why?
FE (Frontend) | c7g.2xlarge | FE is CPU-bound for query planning. Graviton3 (7g) has much faster single-core performance than Graviton2. No NVMe is needed here.
BE (Backend) | r7gd.2xlarge | r (8:1 RAM ratio) is essential for memory-intensive joins from Cube.js. The d provides the local NVMe for the Data Cache.
CN (Compute) | r7gd.2xlarge | Matches the BE. Using the same family simplifies your EKS Node Groups.
Why these matter for your setup:
1. hostPaths vs storageSpec: storageSpec creates a persistent PVC (gp3). hostPaths bypasses the network and maps the physical NVMe drive directly into the pod, which is where you get the microsecond latency for the Data Cache.
2. r family: StarRocks uses a "Vectorized Execution Engine." When joining large Iceberg tables, it builds massive hash tables in memory. c instances (2:1 RAM ratio) will frequently OOM (Out of Memory) during these operations. r instances (8:1) are the standard for production.
3. 7 vs 6: If your region supports it, Graviton3 (7 series) is significantly faster than Graviton2 (6 series) for the specific math StarRocks does during scans and filters.Rocky
08/07/2026, 10:50 AMpre-bootstrap script to format the NVMe drive (e.g., mkfs.xfs /dev/nvme1n1) and mount it to /mnt/nvme0n1 before the pods attempt to start the pods.
References
• quick_start/helm.md
• administration/management/FE_configuration.md
• deployment/helm.md
• sql-reference/sql-statements/cluster-management/storage_volume/CREATE_STORAGE_VOLUME.mdShiv Kumar
08/07/2026, 12:07 PM4.1.4-4a9848e are you sure your helm values.yaml are correct?Rocky
08/07/2026, 12:07 PMvalues.yaml structure requires specific updates because StarRocks 4.0+ introduced simplified Data Cache configurations and the r6gd instance type requires a unique storage strategy to leverage the local NVMe.
The reason you don't see hostPaths in the default values.yaml is that it’s an advanced configuration used primarily for local disk scenarios (like yours). However, the StarRocks Operator correctly reconciles this field into the Pod spec.
Updated values.yaml for StarRocks 4.1.4 (r6gd.2xlarge)
This configuration uses the new 4.0+ parameters (datacache_disk_size) and properly mounts the local NVMe for the Data Cache while keeping gp3 for persistent logs and metadata.
yaml
starrocks:
starrocksCluster:
enabledBe: true
enabledCn: true
starrocksFESpec:
replicas: 3
image: starrocks/fe-ubuntu:4.1.4-4a9848e # Ensure you use the specific version
resources:
requests:
cpu: 4
memory: 16Gi
limits:
cpu: 7
memory: 28Gi
storageSpec:
name: fe
storageClassName: 'gp3'
storageSize: 20Gi
config: |
enable_iceberg_metadata_disk_cache = true
# 4.1 specific: Increased metadata limits for larger catalogs
iceberg_metadata_memory_cache_capacity = 4294967296
iceberg_metadata_disk_cache_capacity = 21474836480
starrocksBeSpec:
replicas: 3
resources:
requests:
cpu: 7 # Leaving 1 core for OS/Daemonsets
memory: 58Gi # Maximize for joins; r6gd.2xlarge has 64GiB total
limits:
cpu: 7
memory: 58Gi
storageSpec:
name: be
storageClassName: 'gp3'
storageSize: 50Gi # Used for metadata/logs/persistent data
# IMPORTANT: Use hostPaths to map the local NVMe from the r6gd host
hostPaths:
- name: local-nvme
hostPath:
path: /mnt/nvme0n1 # Ensure your EKS nodes mount NVMe here
mountPath: /opt/starrocks/be/datacache
config: |
# 4.1+ Data Cache Syntax
datacache_enable = true
datacache_disk_size = 400G
datacache_mem_size = 4G
# Correct multi-path root (gp3 for state; NVMe for cache)
# Syntax: /path,medium:ssd;
storage_root_path = /opt/starrocks/be/storage;/opt/starrocks/be/datacache,medium:ssd
mem_limit = 90%
enable_spill = true
starrocksCnSpec:
replicas: 1
resources:
requests:
cpu: 7
memory: 58Gi
limits:
cpu: 7
memory: 58Gi
hostPaths:
- name: local-nvme-cn
hostPath:
path: /mnt/nvme0n1
mountPath: /opt/starrocks/cn/datacache
config: |
# CN is stateless; use NVMe as the primary root for performance
storage_root_path = /opt/starrocks/cn/datacache,medium:ssd
datacache_enable = true
datacache_disk_size = 400G
datacache_mem_size = 4G
mem_limit = 90%
# 4.1 specific concurrency tuning for Cube.js
brpc_num_threads = 256
pipeline_exec_thread_pool_thread_num = 8
Key Changes for 4.1.x:
1. Simplified Cache Config: In 4.0+, block_cache_disk_size is deprecated. Use datacache_disk_size (e.g., 400G) and datacache_mem_size.
2. hostPaths: This is a valid field for the StarRocks Operator. Even if not in the default Helm example, the Operator reads it from the StarRocksBeSpec section and adds a hostPath volume to the Kubernetes Pod.
3. storage_root_path: In 4.1, adding ,medium:ssd is critical for the optimizer to know that the NVMe is high-performance, which affects its I/O cost estimation for scan plans.
EC2 Family Suggestions for StarRocks 4.1.x
Role | Best Family (Graviton) | Reason
FE | c7g.2xlarge | FE 4.1 query planning is faster on Graviton3 (7-series) than Graviton2 (6-series). No local disk is needed.Rocky
08/07/2026, 12:07 PMr7gd.2xlarge | r (high RAM) is better than m or c for complex joins. The d gives you the local NVMe. 7 is ~25% faster for vector operations than 6.
CN | r7gd.2xlarge | Best for compute-heavy Iceberg scans. The Graviton3 instruction set improves compression/decompression speeds in 4.1.
Important Note on r6gd: EKS does not format or mount the local NVMe drive by default. You must use a pre-bootstrap script in your Node Group (e.g., mkfs.xfs /dev/nvme1n1 && mount /dev/nvme1n1 /mnt/nvme0n1) or the Pods will fail to start because the hostPath directory doesn't exist.
References
• data_source/data_cache.md
• release_notes/release-4.0.md
• administration/management/BE_configuration.md
• deployment/helm.md
• quick_start/helm.md
References
• quick_start/helm.md
• administration/management/BE_configuration.mdShiv Kumar
08/07/2026, 12:57 PMhostPaths and storage_root_path and if yes than what should be the value of these?Rocky
08/07/2026, 12:58 PMhostPaths and storage_root_path.
Karpenter’s instanceStorePolicy: RAID0 only handles the physical formatting and mounting of the NVMe drives to the EC2 host. It does not automatically "pass" that storage into the StarRocks Pods in a way that StarRocks can utilize it for its Data Cache. Without these definitions, StarRocks will use the slower EBS (gp3) volume for caching, wasting the `r6gd`'s NVMe performance.
1. Correct Values for Karpenter (AL2023)
If you are using AL2023 (recommended for Karpenter) with instanceStorePolicy: RAID0, Karpenter mounts the merged NVMe volume to a specific path on the host.
* Host Path: /mnt/k8s-disks/0 (This is the standard RAID0 mount point for AL2023).
* Mount Path: /opt/starrocks/be/datacache (An internal path in the container).
2. Updated values.yaml for 4.1.4 + Karpenter
Update your starrocksBeSpec and starrocksCnSpec like this:
yaml
starrocksBeSpec:
# ... other settings ...
hostPaths:
- name: local-nvme
hostPath:
path: /mnt/k8s-disks/0 # Path created by Karpenter RAID0 on AL2023
mountPath: /opt/starrocks/be/datacache
config: |
# Use gp3 for logs/metadata, use NVMe for cache
# Syntax: path1;path2,medium:ssd
storage_root_path = /opt/starrocks/be/storage;/opt/starrocks/be/datacache,medium:ssd
datacache_enable = true
datacache_disk_size = 400G # Adjust based on r6gd.2xlarge (~474GB available)
datacache_mem_size = 4G
mem_limit = 90%
starrocksCnSpec:
# ... other settings ...
hostPaths:
- name: local-nvme-cn
hostPath:
path: /mnt/k8s-disks/0
mountPath: /opt/starrocks/cn/datacache
config: |
# CN is stateless; point the root directly to NVMe
storage_root_path = /opt/starrocks/cn/datacache,medium:ssd
datacache_enable = true
datacache_disk_size = 400G
3. Instance Family Suggestions (Graviton Edition)
For StarRocks 4.1.4 on ARM64, the "7" series provides a significant boost (roughly 20-30% better performance) over the "6" series for the same price.
Role | Recommended Family | Why?
FE | c7g.2xlarge | FE is CPU-bound. Graviton3 (7g) has much better single-threaded performance for query planning. No NVMe is needed here.
BE | r7gd.2xlarge | r (high RAM) is critical for large joins. The d gives you the local NVMe. Graviton3 handles vectorized math much faster than Graviton2.
CN | r7gd.2xlarge | Same as BE. CNs are often the bottleneck for Iceberg scans, so the extra RAM and newer CPU series help significantly.
Summary Checklist:
1. EC2NodeClass: Ensure instanceStorePolicy: RAID0 is set in your Karpenter EC2NodeClass.
2. AMI Family: If you use amiFamily: Bottlerocket, the mount path may differ from /mnt/k8s-disks/0. For AL2023, it is the standard.
3. Storage Medium: Always add ,medium:ssd to the storage_root_path in 4.1.x so the StarRocks optimizer prioritizes the NVMe for I/O-heavy operations.
References
• data_source/data_cache.md
• using_starrocks/caching/block_cache.md
• administration/management/BE_configuration.md
• deployment/helm.md
• quick_start/helm.md
• administration/management/FE_configuration.md
References
• using_starrocks/caching/block_cache.md
• faq/Deploy_faq.md
• faq/Others.md
• deployment/shared_data/hdfs.mdRocky
08/07/2026, 12:58 PMShiv Kumar
08/07/2026, 1:52 PMFail to open rocksdb, reason:
IO error: While lock file:
/opt/starrocks/be/datacache/datacache/meta/LOCK:
Resource temporarily unavailable
Fail to open RocksDB
path:/opt/starrocks/be/datacache/meta
terminate called without an active exception
...
starcache::StarCacheImpl::_load_all_from_meta_kv()Shiv Kumar
08/07/2026, 1:57 PMRocky
08/07/2026, 1:57 PMhostPaths and storage_root_path.
While Karpenter’s instanceStorePolicy: RAID0 handles the physical formatting and mounting of the NVMe drives to the EC2 host, Kubernetes does not automatically "pass" that host directory into your StarRocks Pods. You have to manually bridge that gap so the StarRocks BE process can see the high-speed local storage.
1. Why hostPaths?
Karpenter (using AL2023) with RAID0 mounts the combined local NVMe storage to a specific directory on the host—typically /mnt/k8s-disks/0. The hostPaths configuration in your Helm values maps this host directory into the StarRocks container.
2. Why storage_root_path?
Simply mounting the drive isn't enough; you must tell the StarRocks BE process to actually use that path for its Data Cache and storage.
Recommended Values for r6gd + Karpenter (AL2023)
In your values.yaml for StarRocks 4.1.4, use the following configuration:
yaml
starrocksBeSpec:
# ... other resources ...
# 1. Map the Karpenter-managed RAID0 mount into the Pod
hostPaths:
- name: local-nvme
hostPath:
path: /mnt/k8s-disks/0 # Standard RAID0 mount point for Karpenter on AL2023
mountPath: /opt/starrocks/be/datacache # Internal path in the container
config: |
# 2. Tell StarRocks to use the mounted path
# Syntax: <path1>;<path2>,medium:ssd
# Note: We keep the default storage for logs/metadata and use NVMe for cache/data.
storage_root_path = /opt/starrocks/be/storage;/opt/starrocks/be/datacache,medium:ssd
# 4.1.x Data Cache Configuration
datacache_enable = true
datacache_disk_size = 400G # r6gd.2xlarge has ~474GB; leave buffer for OS/logs
datacache_mem_size = 4G
mem_limit = 90%
Important Version Note (4.1.4)
Since you are using 4.1.4, you should be aware of a few specific improvements and changes:
* medium:ssd: In 4.1, adding the ,medium:ssd suffix to your storage_root_path is highly recommended. It informs the cost-based optimizer that this specific path is backed by high-performance storage, which influences how it plans I/O-intensive queries.
* Adaptive Layout: 4.1 introduces adaptive tablet distribution. Using the local NVMe for the Data Cache is critical here, as the system will rely on fast disk access to manage shifting data distributions without hitting S3/Iceberg latency.
Summary of Paths
Component | Value
hostPaths.path | /mnt/k8s-disks/0 (Host location)
hostPaths.mountPath | /opt/starrocks/be/datacache (Container location)
storage_root_path | Must include /opt/starrocks/be/datacache,medium:ssd
Verification Tip: After the pods start, you can run kubectl exec -it <be-pod-name> -- df -h to verify that /opt/starrocks/be/datacache is indeed mounted and shows the expected ~400-500GB of NVMe space.
References
• data_source/data_cache.md
• administration/management/BE_configuration.md
• using_starrocks/caching/block_cache.md
• deployment/helm.md
• quick_start/helm.md
• release_notes/release-4.0.md
• faq/Deploy_faq.md
References
• quick_start/helm.md
• deployment/shared_data/feature-support-shared-data.md
• knowledge/usage/storage/hdfs_storage_volume_extended.mdShiv Kumar
08/07/2026, 1:58 PMFail to open rocksdb, reason:
IO error: While lock file:
/opt/starrocks/be/datacache/datacache/meta/LOCK:
Resource temporarily unavailable
Fail to open RocksDB
path:/opt/starrocks/be/datacache/meta
terminate called without an active exception
...
starcache::StarCacheImpl::_load_all_from_meta_kv()Rocky
08/07/2026, 1:58 PMResource temporarily unavailable on the LOCK file) occurs because multiple StarRocks BE pods are being scheduled onto the same EKS node and are trying to use the exact same host directory (/mnt/k8s-disks/0) for their Data Cache metadata.
Since RocksDB (the engine behind the Data Cache meta) requires an exclusive lock on its files, only the first pod to start succeeds. The others fail because they cannot acquire the lock.
To solve this, you have two options: Isolation or Separation.
Option 1: Isolate via Subdirectories (Recommended for Flexibility)
You can use subPathExpr to give each pod its own unique directory (named after the pod) inside the NVMe mount point. This allows multiple BEs to live on one large node without conflicting.
Update your values.yaml as follows:
yaml
starrocksBeSpec:
# ... other settings ...
# Ensure the POD_NAME environment variable is available
envVars:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
hostPaths:
- name: local-nvme
hostPath:
path: /mnt/k8s-disks/0 # The root of the Karpenter RAID0 mount
mountPath: /opt/starrocks/be/datacache
# The Operator will use this to create /mnt/k8s-disks/0/be-0, etc.
subPathExpr: $(POD_NAME)
config: |
storage_root_path = /opt/starrocks/be/storage;/opt/starrocks/be/datacache,medium:ssd
datacache_enable = true
datacache_disk_size = 400G
Option 2: Separate via Pod Anti-Affinity (Recommended for Performance)
For production workloads on r6gd.2xlarge, it is best practice to have one BE pod per node. This prevents CPU/Memory contention and naturally avoids the directory conflict because each pod will be on a different physical NVMe drive.
Add this to your `values.yaml`:
yaml
starrocksBeSpec:
# ... other settings ...
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "<http://starrocks.com/be|starrocks.com/be>" # Adjust this label based on your release name
operator: In
values:
- "true"
topologyKey: "<http://kubernetes.io/hostname|kubernetes.io/hostname>"
Why this is happening in 4.1.4:
In StarRocks 4.0+, the StarCache (Data Cache) implementation uses RocksDB to manage its metadata locally on disk for high performance. Unlike older versions where cache might have been partially in-memory or less strict about locking, 4.1.4 strictly enforces this lock to prevent data corruption in the cache.
Summary Checklist:
1. Check Pod Distribution: Run kubectl get pods -o wide to see if your BE pods are all on the same node.
2. Apply `subPathExpr`: If you want to allow multiple pods per node.
3. Apply `podAntiAffinity`: If you want to ensure each pod gets its own dedicated instance/NVMe.
4. Clean Up: If a pod failed previously, it might have left a "stale" lock. You may need to manually clear the /mnt/k8s-disks/0/datacache directory on the host if the pods still won't start after applying the fix.
References
• administration/management/BE_configuration.md
• using_starrocks/caching/block_cache.md
• data_source/data_cache_troubleshooting.md
• deployment/helm.md
• quick_start/helm.md
References
• quick_start/helm.md
• administration/management/BE_configuration.md
• deployment/deploy_manually.mdRocky
08/07/2026, 2:06 PMIO error: While lock file: /opt/starrocks/be/datacache/datacache/meta/LOCK: Resource temporarily unavailable occurs because multiple Backend (BE) or Compute (CN) pods are trying to use the same directory on the same physical host for their Data Cache metadata.
Since you are using hostPath: /mnt/k8s-disks/0, every pod scheduled on that node maps to the exact same physical folder. RocksDB (used for cache metadata) requires an exclusive lock on its files; when the second pod tries to start, it sees that Pod 1 already owns the lock and crashes.
The Fix: Pod Anti-Affinity
For r6gd.2xlarge instances (8 vCPU, 64GB RAM), you should only run one BE pod per node to avoid resource contention and to solve this locking issue.
Update your values.yaml to include an affinity block for both Backend and Compute nodes. This forces the Kubernetes scheduler to place each pod on a unique node.
yaml
starrocks:
starrocksBeSpec:
# ... previous config ...
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "<http://starrocks.com/be|starrocks.com/be>"
operator: In
values: ["true"]
topologyKey: "<http://kubernetes.io/hostname|kubernetes.io/hostname>"
starrocksCnSpec:
# ... previous config ...
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "<http://starrocks.com/cn|starrocks.com/cn>"
operator: In
values: ["true"]
topologyKey: "<http://kubernetes.io/hostname|kubernetes.io/hostname>"
Why this is happening with Karpenter:
1. Bin-Packing: Even though your BE pod requests almost the entire node, Karpenter or the Kubernetes scheduler might still try to place a CN pod or another BE replica on the same node if the available resources (CPU/RAM) appear sufficient after accounting for overhead.
2. Shared Local Path: Because hostPath is a global reference to the host's filesystem, Pod-0 and Pod-1 will both try to write to /mnt/k8s-disks/0/meta/LOCK.
3. Locks: RocksDB cannot share a data directory. One process = One directory.
Advanced Fix: Unique Subdirectories (if you use very large instances)
If you decide to use larger instances (like r6gd.16xlarge) where you want to run multiple pods per node, you must make the path unique by using the Pod name.
1. Pass the Pod Name into the container.
2. Use the variable in your storage_root_path.
yaml
starrocksBeSpec:
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
config: |
# Adding $(POD_NAME) creates a unique folder for every replica on the host disk
storage_root_path = /opt/starrocks/be/storage;/opt/starrocks/be/datacache/$(POD_NAME),medium:ssd
Rocky's Recommendation: Stick to Pod Anti-Affinity. It is the standard for production database deployments. It ensures high availability (one node failure only takes out one BE) and guarantees that each BE has exclusive access to the local NVMe throughput.
References
• data_source/data_cache_troubleshooting.md
• quick_start/helm.md
• administration/management/BE_configuration.md
• deployment/helm.md
• using_starrocks/caching/block_cache.mdShiv Kumar
08/07/2026, 2:07 PMsubPathExpr is a valid option in helm values cause I don't see this here as well: github.com/StarRocks/starrocks-kubernetes-operator/blob/…/values.yamlRocky
08/07/2026, 2:08 PMsubPathExpr field is a standard Kubernetes Pod feature, but it is not currently exposed in the hostPaths abstraction within the StarRocks Operator's values.yaml.
The Resource temporarily unavailable error occurs because two or more pods (likely a BE and a CN, or two BE replicas) have been scheduled onto the same physical r6gd host and are both trying to lock the same /mnt/k8s-disks/0 directory.
To fix this for StarRocks 4.1.4 on Karpenter, you should use Hard Pod Anti-Affinity and Node Selectors. This ensures that each BE/CN gets its own dedicated NVMe drive on its own node.
1. Updated values.yaml (Production Grade for Karpenter)
This configuration prevents pods from clashing by forcing the scheduler to place only one BE or CN per node.
yaml
starrocksBeSpec:
# Ensure BEs don't land on the same node
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "<http://starrocks.com/be|starrocks.com/be>"
operator: In
values: ["true"]
topologyKey: "<http://kubernetes.io/hostname|kubernetes.io/hostname>"
# IMPORTANT: If you use both BE and CN, they must also avoid each other
# to prevent them from clashing on the same hostPath
nodeSelector:
<http://topology.kubernetes.io/instance-type|topology.kubernetes.io/instance-type>: r6gd.2xlarge # Optional: Pin to r6gd
hostPaths:
- name: local-nvme
hostPath:
path: /mnt/k8s-disks/0
mountPath: /opt/starrocks/be/datacache
config: |
# Path for metadata (gp3) and path for data cache (NVMe)
storage_root_path = /opt/starrocks/be/storage;/opt/starrocks/be/datacache,medium:ssd
datacache_enable = true
datacache_disk_size = 400G
datacache_mem_size = 4G
starrocksCnSpec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "<http://starrocks.com/cn|starrocks.com/cn>" # CNs avoid other CNs
operator: In
values: ["true"]
- key: "<http://starrocks.com/be|starrocks.com/be>" # CNs also avoid BEs to prevent path clash
operator: In
values: ["true"]
topologyKey: "<http://kubernetes.io/hostname|kubernetes.io/hostname>"
hostPaths:
- name: local-nvme-cn
hostPath:
path: /mnt/k8s-disks/0
mountPath: /opt/starrocks/cn/datacache
config: |
storage_root_path = /opt/starrocks/cn/datacache,medium:ssd
datacache_enable = true
datacache_disk_size = 400G
2. Why this is happening even with Anti-Affinity?
If you applied podAntiAffinity and still see the error, check the following:
1. Old Lock Files: Because you are using hostPath, the /mnt/k8s-disks/0/datacache/meta/LOCK file is persistent. If a previous failed deployment left a lock file behind, the new pod might fail to start.
_ Fix: You may need to manually clear the host directory on the node or use a pre-bootstrap script in Karpenter to rm -rf /mnt/k8s-disks/0/_ on node start.
2. BE vs. CN Clash: By default, a BE and a CN can land on the same node. Since both use /mnt/k8s-disks/0, they will fight for the lock. Use the "Inter-Component" anti-affinity shown above (adding <http://starrocks.com/be|starrocks.com/be> to the CN's anti-affinity list).
3. Verification Commands
Run these to see exactly where your pods are landing:
bash
# Check if pods are sharing nodes
kubectl get pods -o wide -l <http://starrocks.com/be=true|starrocks.com/be=true>
kubectl get pods -o wide -l <http://starrocks.com/cn=true|starrocks.com/cn=true>
# Check the BE logs for the specific path it is trying to lock
kubectl logs <be-pod-name> | grep "meta/LOCK"
Recommendation for `r6gd.2xlarge`:
Since an r6gd.2xlarge has exactly 8 vCPUs and 64GB RAM, and your BE is requesting ~7 vCPUs and 58GB RAM, there is zero physical room for another StarRocks pod on that node anyway. Using Hard Anti-Affinity (requiredDuringScheduling...) is the correct architecture here. It forces Karpenter to spin up 3 separate nodes for your 3 BEs.Rocky
08/07/2026, 2:08 PM