Rohit Shetty
03/09/2026, 4:07 PMRocky
03/09/2026, 4:08 PMCREATE RESOURCE GROUP, the definition is stored in the FE (Frontend) metadata. It will survive restarts.
* Global Scope: The definition is global (managed by the FE), but the resource limits (CPU and Memory) are enforced per-node.
* If you set a mem_limit = 0.2, it means each of your 2 CNs will allow that resource group to use up to 20% of its individual query memory pool.
* The concurrency_limit is managed by the FE across the whole cluster for that specific group.
2. How to Edit Them
You can modify an existing resource group at any time using the ALTER RESOURCE GROUP statement. For example:
sql
ALTER RESOURCE GROUP my_group
WITH (
'cpu_weight' = '10',
'mem_limit' = '0.5',
'concurrency_limit' = '20'
);
Changes take effect almost immediately (usually within seconds) across the cluster.
3. Parameters You Can "Play Around" With
The most important parameters are:
* cpu_weight (Soft Limit): Determines the relative share of CPU. If other groups are idle, this group can "borrow" more. (Replaces cpu_core_limit in newer versions).
* exclusive_cpu_cores (Hard Limit): Reserves specific cores just for this group. Other groups cannot use these cores even if this group is idle.
* `mem_limit`: The percentage (0 to 1.0) of the node's query memory pool available to this group.
* `concurrency_limit`: The maximum number of concurrent queries allowed.
* `big_query_cpu_second_limit`: Automatically kills a query in this group if it consumes more than X CPU seconds on a single node.
* `big_query_scan_rows_limit`: Limits how many rows a single query can scan.
4. Behavior with 2 CNs (Scaling)
When you have 2 CNs (or BEs):
* Queries: If you have a concurrency_limit of 10, the FE ensures only 10 queries for that group run simultaneously across the cluster. The CPU/Memory limits apply to the fragments of those queries running on each of the 2 CNs.
* Ingestions: You can create a group specifically for INSERT tasks (like Stream Load or Broker Load).
* Use the query_type classifier: TO (query_type IN ('insert')).
* This ensures that a heavy data load doesn't starve your analytical SELECT queries of CPU or memory.
5. Managing the "Queue"
By default, if a resource group hits its concurrency_limit, new queries will fail with an error.
To make them queue instead of failing, you need to enable the query queue:
1. Set the global variable: SET GLOBAL enable_group_level_query_queue = true;
2. Configure queue parameters in the resource group like max_queued_queries and queued_timeout_ms.
Pro-Tip for Rocky Users:
To see if your queries are actually hitting the right group, you can check the information_schema.resource_group_usage (for real-time) or look at the ResourceGroup field in your Audit Log.
Do you have a specific workload in mind (e.g., high-frequency small inserts vs. giant complex joins) that you're trying to tune for? I can give you some specific parameter recommendations!
References
• faq/resource_isolation_faq.md
• administration/management/resource_management/resource_group.mdRohit Shetty
03/09/2026, 4:10 PMRocky
03/09/2026, 4:10 PMbig_query* parameters are primarily used within Resource Groups to identify and restrict resource-intensive queries, or as session variables to control logging/profiling.
1. Resource Group Parameters (Limits)
These parameters are properties of a resource group and are designed to terminate queries that exceed specific resource thresholds on any single BE node.
Parameter | Default Value | Description
big_query_cpu_second_limit | 0 | The maximum CPU time (in seconds) a query can use on each BE node.
big_query_scan_rows_limit | 0 | The maximum number of rows a query can scan on each BE node.
big_query_mem_limit | 0 | The maximum memory (in bytes) a query can use on each BE node.
How to disable them:
* The default is 0, which means these limits are not in effect (unlimited).
* If you have a resource group where these are set to a positive value and you want to disable the enforcement, you should set them back to 0 using the ALTER RESOURCE GROUP command:
sql
ALTER RESOURCE GROUP your_group_name WITH (
'big_query_cpu_second_limit' = '0',
'big_query_scan_rows_limit' = '0',
'big_query_mem_limit' = '0'
);
2. System Variables (Profiling & Logging)
There are also variables that use the big_query prefix to control observability:
* big_query_profile_threshold:
* Default: 0 (or "" in some versions, effectively disabled).
* Effect: If set (e.g., to 10s), StarRocks will automatically generate a query profile if the query duration exceeds this threshold, even if enable_profile is set to false.
* Does it fail queries? No. It only triggers profile generation for troubleshooting.
* big_query_log_modules (FE Config):
* Default: {"query"}.
* Effect: Controls which modules log into the big_query.log file. This does not affect query execution or success.
Important: Long-Running Queries
If your long-running queries are failing but your big_query_cpu_second_limit is already 0, the failure is likely caused by the query_timeout session variable.
* query_timeout:
* Default: 300 seconds.
* Effect: This is a wall-clock limit. If a query runs longer than this, it is killed.
* To disable/extend: Set it to a very large value (e.g., 86400 for 24 hours).
sql
SET GLOBAL query_timeout = 86400; -- For all new sessions
-- OR --
SET query_timeout = 86400; -- For the current session
Summary for your request:
To ensure "big query" limits are not in effect:
1. Ensure big_query_cpu_second_limit, big_query_scan_rows_limit, and big_query_mem_limit are set to 0 in your resource groups (this is the default).
2. Increase your query_timeout session variable, as this is the most common reason for long-running queries to fail.
References
• administration/management/resource_management/resource_group.md
• faq/resource_isolation_faq.md
• administration/management/monitoring/metrics.mdRohit Shetty
03/09/2026, 4:15 PMDo you have a specific workload in mind (e.g., high-frequency small inserts vs. giant complex joins) that you're trying to tune for? I can give you some specific parameter recommendations!@Rocky Yes, We will have short bursts of inserts, and then in parallel, or with some delay, complex joins. We will also have intermittent queries to export data etc
Rocky
03/09/2026, 4:15 PMbe.conf):
* `compact_threads`: Increase this to allow more parallel compaction. A good rule of thumb is 25% of your total CPU cores (e.g., if you have 32 cores, set to 8).
* `max_cumulative_compaction_num_singleton_deltas`: Set this to 100 (default is often higher). This makes each compaction task smaller and faster, reducing the "compaction score" quickly during bursts.
* `write_buffer_size`: Increase to 256MB or 512MB (default 100MB) if your bursts involve large amounts of data, to reduce the frequency of flushing small files to disk.
* Frontend (FE) Configuration:
* If using Shared-Data (Cloud-native): Set lake_compaction_max_tasks to -1 (adaptive) or a higher fixed number to trigger more concurrent tasks.
2. Tuning for Complex Joins
Since you have parallel inserts, you must protect your join performance from being "starved" of CPU or memory.
* Resource Groups (Crucial): Create separate resource groups to isolate the inserts from the joins. This prevents a heavy join from blocking an insert, and vice-versa.
sql
-- Example: Create a group for complex joins
CREATE RESOURCE GROUP 'analytics_group'
PROPERTIES (
"cpu_weight" = "10",
"mem_limit" = "0.6", -- Allocate 60% of BE memory
"concurrency_limit" = "20"
);
* Spill to Disk: For very complex joins that might hit memory limits, enable spilling:
* Set enable_spill = true in your session or resource group.
* Pipeline Engine: Ensure enable_pipeline_engine = true (default in 3.x) is on, as it handles parallel join execution much more efficiently than the old engine.
3. Tuning for Intermittent Exports
Exports can be resource-intensive because they scan large amounts of data and serialize it.
* Export FE Parameters:
* `export_task_pool_size`: Keep this at a low value (e.g., 3-5) so that export tasks don't take over all available threads during your join windows.
* `export_max_bytes_per_be_per_task`: Set to 256MB or 512MB. This controls how StarRocks splits the export job into smaller tasks.
* Resource Group Classification: Assign your export user or query type to a specific resource group with a lower cpu_weight so it runs in the background without impacting the complex joins.
sql
-- Classify inserts and exports separately
CREATE RESOURCE GROUP 'load_group' PROPERTIES ("cpu_weight" = "2", "mem_limit" = "0.2");
ALTER RESOURCE GROUP 'load_group' ADD CLASSIFIER (query_type = 'insert');
Summary Checklist:
1. Batch your inserts: Even with "bursts," try to avoid INSERT INTO ... VALUES (1,2,3) one by one. Use Stream Load or batch inserts of at least 100+ rows.
2. Monitor Compaction: Run SHOW PROC '/compactions'; during a burst. If the "Score" is consistently > 100, increase your compact_threads.
3. Memory Limits: Monitor load_process_max_memory_limit_percent (default 30%) to ensure your insert bursts don't consume all the memory needed for your complex joins.
Does your "short burst" usually come from a specific source like Kafka, or are they manual SQL inserts? I can give you the exact Stream Load or Routine Load settings if needed!
ReferencesRocky
03/09/2026, 4:15 PMRohit Shetty
03/09/2026, 4:25 PMmem_limit work in resource group queues?Rocky
03/09/2026, 4:25 PMmem_limit parameter in a resource group works as a hard limit for execution and a reference for spilling, rather than a direct "queuing" trigger like concurrency.
Here is a breakdown of how it functions within the resource management and queuing system:
1. Hard Execution Limit
mem_limit specifies the percentage of the BE's query memory pool (by default, 90% of BE RAM) that a resource group can consume.
* Per-BE Enforcement: This limit is enforced on each BE node independently.
* Failure on Overrun: If the total memory used by all running queries in a resource group exceeds this limit on a specific BE, new memory allocations will fail, and the query will typically be terminated with a Memory limit exceeded error.
* No Native Queuing: Unlike concurrency_limit, exceeding the mem_limit during execution does not put the query into a queue; it results in a failure.
2. Interaction with Query Queues
StarRocks has two types of queues where memory plays different roles:
* Global Query Queue: You can set a memory threshold for the entire BE using query_queue_mem_used_pct_limit. If the total BE memory exceeds this percentage, all new incoming queries (regardless of resource group) are queued until memory usage drops.
* Resource Group Queue: Triggered when enable_group_level_query_queue is set to true. However, the queuing triggers for resource groups are specifically concurrency_limit and max_cpu_cores. The mem_limit is not currently used as a pre-check trigger to "queue" a query before it starts; it is enforced once the query begins running.
3. Memory Spilling (v3.1.7+)
The mem_limit works with the spill_mem_limit_threshold to prevent query failures:
_ If a resource group's memory usage exceeds mem_limit _ spill_mem_limit_threshold, StarRocks will begin spilling intermediate data to disk for queries within that group.
* This allows the group to continue processing even when it is close to its mem_limit, effectively "stretching" the available memory at the cost of disk I/O.
4. Shared Memory Pools (v4.0+)
Using the mem_pool parameter, you can group multiple resource groups together to share a single mem_limit.
* Example: If RG1 and RG2 are both in shared_pool with a mem_limit of 50%, they collectively can use up to 50% of the BE query memory. If RG1 uses 40%, RG2 only has 10% remaining before reaching the limit.
Summary Table
Feature | Triggered By | Result
Queuing (Global) | query_queue_mem_used_pct_limit | Queries wait in a global queue.
Queuing (Group) | concurrency_limit, max_cpu_cores | Queries wait in a group-specific queue.
Spilling | mem_limit * spill_mem_limit_threshold | Data spills to disk to save memory.
Execution Limit | mem_limit | Query fails if exceeded during runtime.
References
• faq/resource_isolation_faq.md
• administration/management/resource_management/resource_group.md
• administration/management/resource_management/query_queues.mdJonathan Wills
03/09/2026, 5:23 PMRocky
03/09/2026, 5:24 PMuser: The name of the user who initiated the query.
* role: The role of the user.
* query_type: The type of query (supported values are SELECT and INSERT).
* source_ip: The CIDR block (IP range) from which the query is initiated.
* db: The database being accessed by the query.
* plan_cpu_cost_range: The system-estimated CPU cost of the query (available from v3.1.4 onwards).
* plan_mem_cost_range: The system-estimated memory cost of the query (available from v3.1.4 onwards).
──────────
Applying Resource Groups at Query Time
While the classifiers mentioned above are the primary way to automate routing (based on user, DB, etc.), you can also specify or override the resource group at query time or session time.
1. Session/Query Level Override:
Instead of relying purely on user-based classifiers, you can manually set the resource group for your current session. This is effectively "at query time" because it overrides the default classifier logic:
sql
-- Directs all subsequent queries in this session to 'my_resource_group'
SET resource_group = 'my_resource_group';
2. Does it need to be user-based?
No, it does not have to be strictly user-based. You can route based on the Source IP, the Database being queried, or even the estimated cost of the query.
3. Query Tags:
StarRocks does not currently support a "tag" as a standard dimension within the classifier definition (i.e., you can't create a classifier like TO (tag='analytics')). However, using the SET resource_group command before a query is the standard way to achieve dynamic, per-query routing.
Example of creating a group with multiple dimensions:
sql
CREATE RESOURCE GROUP analytic_group
TO
(user='alice', role='analyst'), -- User/Role based
(db='sales_reports'), -- Database based
(source_ip='192.168.1.0/24') -- Network based
WITH (
"cpu_weight" = "10",
"mem_limit" = "20%"
);
References
• administration/management/resource_management/resource_group.mdNancy Wang
04/09/2026, 3:19 AMRocky
04/09/2026, 3:19 AMdb_a or logs in with user user_a.
* Product B: Uses db_b or logs in with user user_b.
2. Enable Resource Isolation
Resource groups require the Pipeline Engine (enabled by default in StarRocks 3.1.0+). To be safe, ensure it is enabled globally:
sql
SET GLOBAL enable_pipeline_engine = true;
3. Create Resource Groups
You can choose between two types of CPU limits:
* cpu_weight (Shared): Flexible. If one product is idle, the other can use more CPU. If both are busy, they get CPU based on the weight ratio.
* exclusive_cpu_cores (Exclusive): Hard limit. The cores are reserved solely for that group.
Example: Isolation based on Database
If you want Product A to have 60% and Product B to have 40% of resources:
sql
-- Resource Group for Product A
CREATE RESOURCE GROUP product_a_group
TO (db='db_product_a')
WITH (
"cpu_weight" = "60",
"mem_limit" = "50%",
"concurrency_limit" = "100"
);
-- Resource Group for Product B
CREATE RESOURCE GROUP product_b_group
TO (db='db_product_b')
WITH (
"cpu_weight" = "40",
"mem_limit" = "30%",
"concurrency_limit" = "50"
);
Example: Isolation based on User
If Product A and B use specific database users:
sql
CREATE RESOURCE GROUP product_a_group
TO (user='prod_a_user')
WITH (
"cpu_weight" = "10",
"mem_limit" = "40%"
);
4. Key Parameters Explained
* TO (Classifiers): This is how StarRocks knows which query belongs to which group. You can use user, role, db, or source_ip.
* `cpu_weight`: A relative value compared to other groups.
* `mem_limit`: The maximum percentage of memory on each BE node this group can use.
* `concurrency_limit`: Limits the number of concurrent queries to prevent a single product from overwhelming the cluster.
* `big_query_mem_limit`: (Optional) You can add this to kill "rogue" queries that exceed a certain memory threshold.
5. Managing Resource Groups
* View all groups: SHOW RESOURCE GROUPS ALL;
* Update a group:
sql
ALTER RESOURCE GROUP product_a_group WITH ("cpu_weight" = "80");
* Delete a group: DROP RESOURCE GROUP product_a_group;
Best Practices for Production
1. Monitor Usage: Use the Information_schema.resource_group_usage (if available in your version) or audit logs to see if your limits are too restrictive.
2. Default Group: Queries that don't match any classifier will fall into the default_wg. Ensure your important products have specific classifiers so they don't compete with "unknown" traffic.
3. Small Queries vs Big Queries: If one product has both dashboarding (fast) and ETL (slow) queries, you can create two groups for the same product using the query_type classifier (e.g., query_type in ('select') vs query_type in ('insert')).
References
• sql-reference/sql-statements/cluster-management/resource_group/CREATE_RESOURCE_GROUP.md
• administration/management/resource_management/resource_group.mdNancy Wang
04/09/2026, 3:21 AMRocky
04/09/2026, 3:21 AMdb_product_c or a new user user_c) and what its priority is relative to the others.
2. Create the Resource Group for Product C
If you want Product C to have a specific share of resources, create its group.
Example: Shared Resource Mode (Using cpu_weight)
In this mode, if the cluster is busy, CPU is distributed based on the ratio of weights.
sql
CREATE RESOURCE GROUP product_c_group
TO (db='db_product_c') -- or (user='user_c')
WITH (
"cpu_weight" = "30",
"mem_limit" = "20%",
"concurrency_limit" = "50"
);
3. Rebalance Existing Groups (Important)
When you add a third product, the "pie" gets split into more pieces. You should use ALTER RESOURCE GROUP to adjust the original products if their current weights/limits are now too high.
Scenario: You have 100% capacity to split.
* Old Setup: Product A (60), Product B (40). Total = 100.
* New Setup: You want a 40/30/30 split.
sql
-- Adjust Product A down from 60 to 40
ALTER RESOURCE GROUP product_a_group WITH ("cpu_weight" = "40", "mem_limit" = "40%");
-- Adjust Product B down from 40 to 30
ALTER RESOURCE GROUP product_b_group WITH ("cpu_weight" = "30", "mem_limit" = "30%");
-- Product C (created in step 2) takes the remaining 30
Key Considerations for Scaling to Multiple Products:
* Weight is Relative: cpu_weight is not a percentage. If Group A has weight 10 and Group B has weight 10, they split resources 50/50. If you add Group C with weight 10, they all automatically split resources 33/33/33.
* Memory Sums: The mem_limit is a hard limit for that specific group. Ensure the sum of mem_limit across all groups (including the default_wg) is managed carefully. While StarRocks allows the sum to exceed 100%, it's best practice to keep the total around 80-90% to leave room for system tasks.
* Exclusive Cores: If Product C is a "Critical Dashboard" that must never be slow, consider using exclusive_cpu_cores instead of cpu_weight. This reserves physical CPU cores that other products cannot touch.
_ _Note: Only use this for highly critical, small-scale workloads.*
How to Check the New Balance
After adding the third product, run this to see the current distribution of all products:
sql
SHOW RESOURCE GROUPS ALL;
This will show you the weights, memory limits, and the assigned classifiers (databases/users) for all three products side-by-side.
References
• administration/management/resource_management/resource_group.md
• sql-reference/sql-statements/cluster-management/resource_group/CREATE_RESOURCE_GROUP.mdNancy Wang
04/09/2026, 3:23 AMRocky
04/09/2026, 3:23 AMdefault_wg. This group is a "catch-all" for any query that doesn't match your product-specific classifiers (such as queries from the admin user, internal system tasks, or accidental queries against other databases).
By default, default_wg has a very high priority (cpu_weight equals the number of CPU cores and mem_limit is 100%). If you don't configure it, it could potentially starve your products of resources.
Here is how to configure it correctly:
1. The "Safety Buffer" Strategy (Recommended)
In this approach, you allocate a small "slice" of the cluster to the default_wg to ensure the system remains stable and manageable, while giving the bulk of resources to your products.
Example Allocation:
* Product A: 40% CPU / 40% Mem
* Product B: 30% CPU / 25% Mem
* Product C: 25% CPU / 25% Mem
* default_wg: 5% CPU / 10% Mem (Safety buffer)
2. Configuration SQL
You can modify the default_wg just like any other group using ALTER RESOURCE GROUP. Note that you cannot add classifiers to it; it always catches everything else.
sql
-- 1. Adjust your existing products to make room (Total 95%)
ALTER RESOURCE GROUP product_a_group WITH ("cpu_weight" = "40", "mem_limit" = "40%");
ALTER RESOURCE GROUP product_b_group WITH ("cpu_weight" = "30", "mem_limit" = "25%");
ALTER RESOURCE GROUP product_c_group WITH ("cpu_weight" = "25", "mem_limit" = "25%");
-- 2. "Shrink" the default group so it doesn't take over
-- Set weight to a low number (e.g., 5) and limit its memory
ALTER RESOURCE GROUP default_wg WITH (
"cpu_weight" = "5",
"mem_limit" = "10%"
);
3. Understanding the Mechanics
* CPU Weight is Relative: The cpu_weight is a ratio. If the total of all weights is 100 (40+30+25+5), then a weight of 5 for default_wg means it gets exactly 5% of CPU cycles when the cluster is under full load. If the products are idle, the default_wg can still use more.
* Memory Limit is a Hard Cap: mem_limit is a percentage of the total memory on each BE. If the sum of all mem_limit exceeds 100% (over-provisioning), StarRocks allows it, but you risk the Backend (BE) process hitting its global limit and killing queries if everyone tries to use their full limit at once. It is best to keep the sum around 90-100%.
* Don't set mem_limit to 0% for `default_wg`: You still need to run basic metadata queries or maintenance tasks. Setting it too low (e.g., <5%) might cause system queries to fail with "Memory limit exceeded."
4. How to Verify
After applying the changes, run this command to see the new "pie chart" of your cluster:
sql
SHOW RESOURCE GROUPS ALL;
Check that the cpu_weight and mem_limit columns align with your plan across your products and the default_wg.
References
• administration/management/resource_management/resource_group.md
• sql-reference/sql-statements/cluster-management/resource_group/ALTER_RESOURCE_GROUP.md
References
• administration/management/resource_management/resource_group.md
• sql-reference/sql-statements/cluster-management/resource_group/ALTER_RESOURCE_GROUP.md
• sql-reference/sql-statements/cluster-management/resource_group/CREATE_RESOURCE_GROUP.mdNancy Wang
04/09/2026, 3:25 AMRocky
04/09/2026, 3:25 AMCROSS JOIN without a filter, the big-query limit will kill that specific query once it hits the threshold, rather than letting it consume 100% of the Backend (BE) memory and causing an Out-of-Memory (OOM) crash for the whole node.
* Different SLAs: You can set different "patience" levels for different products.
* Dashboard Product: Might have a strict 20s CPU limit because users expect fast results.
* Data Science Product: Might have a 300s CPU limit because they run complex analytical jobs.
* Predictable Performance: It ensures that one "heavy" product cannot hog the shared resources (CPU/Scan rows) indefinitely.
2. The 3 Key "Big Query" Parameters
You can add these to your CREATE or ALTER RESOURCE GROUP statements:
Parameter | Description
big_query_cpu_second_limit | Max CPU time (in seconds) a query can use on a single BE.
big_query_scan_rows_limit | Max number of rows a query can scan on a single BE.
big_query_mem_limit | Max memory (in bytes) a query can use on a single BE.
3. Practical Example
Let's say Product A is a user-facing app (needs protection from slow queries) and Product B is an internal reporting tool (allows heavier queries).
sql
-- Product A: Strict limits (Kill queries > 30s CPU or > 5GB RAM per BE)
ALTER RESOURCE GROUP product_a_group WITH (
"big_query_cpu_second_limit" = "30",
"big_query_mem_limit" = "5368709120", -- 5GB
"big_query_scan_rows_limit" = "100000000" -- 100M rows
);
-- Product B: Relaxed limits (Kill queries > 5 min CPU or > 20GB RAM per BE)
ALTER RESOURCE GROUP product_b_group WITH (
"big_query_cpu_second_limit" = "300",
"big_query_mem_limit" = "21474836480" -- 20GB
);
4. Important Implementation Tips
1. Limits are Per-Node: Remember that big_query_mem_limit = 5GB means 5GB on each BE. If you have 3 BEs, the query could technically use up to 15GB total across the cluster.
2. Start High, then Tighten: If you aren't sure what the limits should be, start with very high values (or 0 to disable). Monitor your fe.audit.log or information_schema to see typical query usage, then set the limit slightly above the 99th percentile of your "normal" queries.
3. Default Group Protection: Always set big-query limits on your default_wg. This prevents unauthorized users or accidental "un-classified" queries from impacting your production products.
Summary
Setting these limits is the difference between "one user ran a bad query and the whole cluster is slow" and "one user ran a bad query and only they got an error message." For 'Exceeding Big Query Limit'."* It'."* It'."* It'."* It'."* It'."* It'."* Iimit'."* It'."* It'."* It'."**
References
• administration/management/monitor_manage_big_queries.md
• administration/management/resource_management/resource_group.md
• faq/resource_isolation_faq.md
References
• faq/resource_isolation_faq.md
• administration/management/monitor_manage_big_queries.md
• administration/management/resource_management/resource_group.mdNancy Wang
04/09/2026, 3:28 AMRocky
04/09/2026, 3:28 AMbig_query_..._limit parameters. If a query exceeds these, it is killed.
* Best for: General protection where you don't mind if a medium-sized query uses the same resources as a small query.
* Configuration:
sql
ALTER RESOURCE GROUP product_a_group WITH (
"big_query_cpu_second_limit" = "100", -- Kills query if > 100s CPU
"big_query_mem_limit" = "1073741824" -- Kills query if > 1GB RAM
);
Option 2: Two Resource Groups (Advanced Isolation)
Goal: Ensure that a long-running analytical query doesn't make a 100ms dashboard query take 5 seconds.
You can use Classifiers based on the estimated cost of a query (plan_cpu_cost_range) to automatically route queries to a "Fast Lane" or a "Batch Lane."
* Best for: Products with mixed workloads (e.g., a dashboard and a data export tool using the same user/DB).
* How it works:
1. Product A - Short Group: High cpu_weight, low concurrency_limit, and strict big_query limits.
2. Product A - Long Group: Lower cpu_weight (so it doesn't starve the short queries) and relaxed big_query limits.
Example Configuration:
sql
-- 1. Create the "Fast Lane" for Product A
CREATE RESOURCE GROUP product_a_short
TO (db='db_a', plan_cpu_cost_range='(0, 1000000]') -- Routes small queries here
WITH (
"cpu_weight" = "80",
"big_query_cpu_second_limit" = "10" -- Kill if it accidentally runs long
);
-- 2. Create the "Batch Lane" for Product A
CREATE RESOURCE GROUP product_a_long
TO (db='db_a', plan_cpu_cost_range='(1000000, -1]') -- Routes heavy queries here
WITH (
"cpu_weight" = "20",
"big_query_cpu_second_limit" = "3600" -- Allow up to 1 hour
);
Which should you choose?
* Start with Option 1 (One Group): It is much easier to manage. Most users find that setting the big_query_..._limit on a single group is enough to keep the cluster stable.
* Move to Option 2 (Two Groups) ONLY IF: You notice that when Product A runs a "big" query, the "small" queries for the same product become noticeably slower.
Key Performance Note:
From v3.3.5 onwards, if you have a "Short Query" group that must be fast, you should use exclusive_cpu_cores instead of cpu_weight. This reserves physical CPU cores for that group so they are never "borrowed" by other products.
References
• administration/management/resource_management/resource_group.md
• faq/resource_isolation_faq.md
• administration/management/monitor_manage_big_queries.md
References
• administration/management/resource_management/resource_group.mdNancy Wang
04/09/2026, 3:30 AMRocky
04/09/2026, 3:31 AMbig_query limits within that single group. If a query is truly "bad," it gets killed. If it’s just "heavy," it runs but is throttled by the product's overall cpu_weight.
* Key Settings:
* cpu_weight: Set this to represent the product's priority relative to others.
* big_query_cpu_second_limit: Set this to a "sanity check" value (e.g., 300s). This prevents a single product from spinning the CPU for an hour on a bad query.
──────────
Strategy 2: Two Resource Groups per Product (Recommended for High SLA / Mixed Workloads)
Use this only for products that have both high-concurrency/fast dashboard queries and heavy data-science/reporting queries coming from the same user or database.
* Why: To prevent a "Line-of-Blockage." In a single group, a massive query might not kill the cluster, but it could make your 100ms dashboard query take 2 seconds because they are competing for the same slice of the product's CPU weight.
* How to implement: Use the plan_cpu_cost_range classifier to automatically route queries.
* Group A (Fast): plan_cpu_cost_range = (0, 1000000]. Give it a high cpu_weight or even exclusive_cpu_cores (if on v3.3.5+).
* Group B (Batch): plan_cpu_cost_range = (1000000, -1]. Give it a lower cpu_weight.
──────────
The "Rocky" Recommended Blueprint
If I were setting up your cluster today, here is the specific configuration I would use for Product A:
Goal | Parameter | Value | Reason
Stability | big_query_mem_limit | 20-30% of BE RAM | Prevents "Out of Memory" crashes.
Stability | big_query_cpu_second_limit | 300 | Prevents "Infinite Loop" or poorly written queries.
SLA | exclusive_cpu_cores | 2 - 4 | (v3.3.5+) Guarantees a "fast lane" that other products cannot touch.
Concurrency | concurrency_limit | 100 | Prevents "Query Flooding" from a single product.
Summary Checklist:
1. Don't over-complicate: Start with one group per product.
2. Always set limits: Put big_query_mem_limit and big_query_cpu_second_limit on every group, including default_wg.
3. Monitor first: Use the fe.audit.log or the information_schema.be_audit_log to see the actual cpuCostNs and memUsageBytes of your products before tightening the limits.
Pro-tip: If you use StarRocks v3.3.5 or later, use exclusive_cpu_cores for your most important product's "short query" group. This provides "hard isolation," ensuring those queries are never delayed by other workloads.
References
• administration/management/resource_management/resource_group.md
• faq/resource_isolation_faq.md
• best_practices/audit_log_resource_group.md
References
• sql-reference/sql-statements/cluster-management/resource_group/CREATE_RESOURCE_GROUP.md
• administration/management/resource_management/resource_group.md
• best_practices/audit_log_resource_group.mdRocky
04/09/2026, 3:31 AMNancy Wang
04/09/2026, 6:16 AMRocky
04/09/2026, 6:17 AMCREATE RESOURCE GROUP (for new products) and ALTER RESOURCE GROUP (for the existing default_wg) commands.
1. Apply Configuration for Products A, B, and C
For CPU percentages, we set the cpu_weight proportionally (40, 30, 25, 5). For Memory, we use the mem_limit parameter with a percentage string.
sql
-- Product A: 40% CPU, 40% Memory
CREATE RESOURCE GROUP product_a_group
TO (db='db_a') -- Replace with your actual classifier (user, role, or db)
WITH (
"cpu_weight" = "40",
"mem_limit" = "40%",
"big_query_mem_limit" = "10737418240" -- Example: 10GB limit per query (in bytes)
);
-- Product B: 30% CPU, 25% Memory
CREATE RESOURCE GROUP product_b_group
TO (db='db_b')
WITH (
"cpu_weight" = "30",
"mem_limit" = "25%",
"big_query_mem_limit" = "5368709120" -- Example: 5GB limit per query
);
-- Product C: 25% CPU, 25% Memory
CREATE RESOURCE GROUP product_c_group
TO (db='db_c')
WITH (
"cpu_weight" = "25",
"mem_limit" = "25%",
"big_query_mem_limit" = "5368709120"
);
2. Configure default_wg (Safety Buffer)
Since default_wg is a system-defined group, you must use ALTER. This group captures any queries that don't match the classifiers of Products A, B, or C.
sql
ALTER RESOURCE GROUP default_wg WITH (
"cpu_weight" = "5",
"mem_limit" = "10%",
"big_query_mem_limit" = "2147483648" -- Example: 2GB limit for "unknown" queries
);
Important Technical Details:
1. cpu_weight vs Percentage: StarRocks uses a weight system. Since your requested values (40+30+25+5) add up to exactly 100, the weight effectively acts as a percentage of the total CPU capacity when all groups are active.
2. big_query_mem_limit is in Bytes: Unlike mem_limit, this parameter requires a numeric value in bytes.
* 1073741824 = 1 GB
* 5368709120 = 5 GB
* 10737418240 = 10 GB
3. Per-Node Limits: These limits are enforced on each Backend (BE) node. If you set a big_query_mem_limit of 10GB and you have 3 BEs, a distributed query could technically consume up to 30GB of memory across the cluster before being killed.
4. Memory Sum: StarRocks allows the sum of mem_limit across all groups to exceed 100%. However, in your case, it equals 100%, which is a safe and "hard" allocation strategy.
Recommendation for big_query_mem_limit value:
You should set big_query_mem_limit to a value slightly lower than the total memory available to that resource group in bytes. For example, if your BE has 100GB of RAM and Product A has a 40% mem_limit (40GB), setting big_query_mem_limit to 20GB or 30GB ensures one query doesn't starve other queries within the same product.
References
• administration/management/resource_management/resource_group.md
• sql-reference/sql-statements/cluster-management/resource_group/CREATE_RESOURCE_GROUP.md
• faq/resource_isolation_faq.md
References
• administration/management/resource_management/resource_group.md
• sql-reference/sql-statements/cluster-management/resource_group/CREATE_RESOURCE_GROUP.md
• faq/resource_isolation_faq.md
• administration/management/monitor_manage_big_queries.md
• administration/management/monitor_manage_big_queries.mdRocky
04/09/2026, 6:17 AMNancy Wang
04/09/2026, 6:20 AMRocky
04/09/2026, 6:20 AMdefault_wg is idle.
In StarRocks, the mem_limit for a resource group acts as a hard ceiling (quota), but it is not a physical reservation. Here is how it works:
1. Limits are Quotas, not Reservations
Setting a 10% memory limit for default_wg does not physically carve out 10% of your RAM and hide it from other groups. It simply means that if a query lands in the default group, it cannot use more than 10% of the BE's query memory.
If no queries are running in default_wg, that physical RAM remains available for the system and other resource groups to use (up to their own respective limits).
2. You Can Over-Subscribe (Total > 100%)
StarRocks allows the sum of all mem_limit values to exceed 100%. This is the best way to prevent "waste."
If you want your products to be able to use extra memory when the cluster is quiet, you should set their limits slightly higher. For example:
* Product A: 60% (instead of 40%)
* Product B: 50% (instead of 30%)
* Product C: 40% (instead of 25%)
* default_wg: 20% (instead of 5%)
Why do this?
* If only Product A is running, it can now use up to 60% of the RAM, which is better for performance.
* If all products start running at the same time and hit their limits, StarRocks' internal memory tracker will manage the pressure. However, queries will only fail if they exceed their own group limit or if the total BE memory usage hits the process limit (usually 90% of RAM).
3. Recommendation for your setup
If you want to stick to your original plan but ensure no capacity is "locked away," you can simply set the default_wg higher (e.g., 50% or even 100%) and leave your product groups at your desired percentages.
Revised Recommendation:
To keep things safe but flexible, I suggest:
1. Set Product limits to what you want them to "guarantee" themselves.
2. Over-subscribe the total. If Product A is your most important product, give it a mem_limit of 80%. This way, if Products B and C are idle, Product A can use almost the whole machine. It will only be restricted to its "fair share" if other groups are also active and competing for RAM.
Key Difference: CPU vs. Memory
* CPU (cpu_weight): This is "soft." If Product A is idle, its 40% CPU weight is automatically and instantly shared among B and C. No configuration is needed to avoid "waste."
* Memory (mem_limit): This is "hard." A group cannot exceed its limit even if the rest of the machine is empty. To avoid waste here, you must over-subscribe the percentages.
References
• administration/management/resource_management/resource_group.md
• faq/resource_isolation_faq.md
References
• faq/resource_isolation_faq.md
• administration/management/resource_management/resource_group.md
• best_practices/audit_log_resource_group.mdNancy Wang
04/09/2026, 7:05 AMquery_queue_options
吗Rocky
04/09/2026, 7:06 AMquery_queue_options 的资源组属性(Property)*。
你可能是在查阅较新版本(如 v3.3+)的内部配置或 FE 配置项时看到了相关的术语。在 StarRocks 的标准 SQL 语法中,针对资源组的查询队列配置,通常是通过以下*参数*和*系统变量*来完成的:
1. 资源组内的队列相关参数
在 CREATE RESOURCE GROUP 或 ALTER RESOURCE GROUP 的 WITH 子句中,你可以直接设置触发排队的阈值:
* concurrency_limit: 限制该资源组在单个 BE 上的最大并发查询数。超过此限制的查询会进入队列(如果启用了组级队列)。
* max_cpu_cores (v3.1.4+): 限制该资源组在单个 BE 上可使用的 CPU 核心数。
示例用法:
sql
ALTER RESOURCE GROUP product_a_group WITH (
"concurrency_limit" = "20", -- 超过 20 个并发即排队
"max_cpu_cores" = "10" -- 超过 10 核占用即排队
);
2. 必须开启的开关
要让资源组级别的排队生效,必须设置以下全局变量:
sql
-- 1. 开启组级别的查询队列(核心开关)
SET GLOBAL enable_group_level_query_queue = true;
-- 2. 开启 SELECT 查询排队
SET GLOBAL enable_query_queue_select = true;
3. 全局队列控制变量 (类似 Options)
如果你指的 options 是控制排队行为(如等待多久、队列多长),这些通常是通过*系统变量*全局配置的,目前不支持在单个资源组内差异化设置:
变量名 | 默认值 | 描述
query_queue_max_queued_queries | 1024 | 队列最大容纳查询数,超过后新查询直接报错拒绝。
query_queue_pending_timeout_second | 300 | 查询在队列中等待的最长时间(秒),超时则报错。
4. 关于 "Query Queue V2" (v3.3.4+ 引入)
在 StarRocks v3.3.4 及以后的 FE 配置中,确实出现了 `enable_query_queue_v2`。该版本引入了更精细的调度策略(如 `SlotSelectionStrategyV2`)。
* 如果你是在 FE 配置文件 fe.conf 中看到了类似 query_queue_v2_xxx 的参数,这些是 *FE 配置项*,用于调整全局调度器的行为,而不是通过 SQL 在资源组上设置的。
总结建议
如果你是想配置资源组的排队逻辑:
1. *设置阈值*:使用资源组的 `concurrency_limit`。
2. *激活功能*:确保 enable_group_level_query_queue 已开启。
3. *调整超时/长度*:通过 SET GLOBAL query_queue_pending_timeout_second = ... 来调整。
如果你在特定文档或代码中看到了 query_queue_options 这个具体的 Key,请提供上下文,我可以为你确认它是否属于某个特定的 Enterprise 特性或未公开的实验性配置。
References
• administration/management/resource_management/query_queues.mdNancy Wang
04/09/2026, 7:15 AMRocky
04/09/2026, 7:15 AMcpu_weight. When the system is fully loaded (all groups want CPU), StarRocks distributes CPU time based on the ratio of their weights.
* Group A (cpu_weight=80)
* Group B (cpu_weight=20)
* Contention Result: Group A will get 80% of the CPU cycles, and Group B will get 20%.
* Idle Behavior: If Group A is idle, Group B can use 100% of the CPU. This ensures no "waste."
sql
ALTER RESOURCE GROUP group_a WITH ("cpu_weight" = "80");
ALTER RESOURCE GROUP group_b WITH ("cpu_weight" = "20");
2. Hard Priority (Exclusive CPU Cores)
If you want to ensure Group A always has priority regardless of how busy Group B is, you can use exclusive_cpu_cores (v3.1.4+). This physically reserves a specific number of cores for that group.
* Shared Groups: Run on "Shared Cores" and compete via weights.
* Exclusive Groups: Have their own dedicated "Exclusive Cores." They don't have to scramble with others.
sql
-- Reserve 8 cores exclusively for Group A
ALTER RESOURCE GROUP group_a WITH ("exclusive_cpu_cores" = "8");
_Note: Only one of cpu_weight or exclusive_cpu_cores can be set._
3. Concurrency Priority (Queueing)
To prevent one group from "scrambling" by launching thousands of small queries that swamp the scheduler, use concurrency_limit. This forces the "lesser" group to wait in a queue before they can even begin to compete for CPU.
sql
-- Limit Group B to 5 concurrent queries to give Group A "room"
ALTER RESOURCE GROUP group_b WITH ("concurrency_limit" = "5");
4. Memory Pressure (No "Priority")
Memory is handled differently. It is a Hard Limit. There is no "priority" for memory—if Group B hits its mem_limit, its queries will fail or spill to disk, regardless of whether Group A is using its memory or not.
To give Group A more "priority" for memory, simply give it a much higher mem_limit percentage than Group B.
Summary Comparison
Goal | Mechanism | Behavior
Relative Importance | cpu_weight | Proportional sharing under load; full use when idle.
Strict Guarantee | exclusive_cpu_cores | Fixed core count; zero interference from other groups.
Throughput Control | concurrency_limit | Limits the number of active queries to prevent cluster flooding.
Safety Buffer | max_cpu_cores | Limits a group to a max core count even if the machine is idle.
Rocky's Tip: For a production "Product A vs Product B" scenario, I recommend setting a high cpu_weight for your primary product and a lower one for the background product. This keeps the cluster efficient while protecting your VIP users during spikes.
References
• administration/management/resource_management/resource_group.md
• faq/resource_isolation_faq.md
• administration/management/resource_management/query_queues.md
References
• faq/resource_isolation_faq.md
• administration/management/resource_management/resource_group.md
• administration/management/resource_management/query_queues.mdNancy Wang
04/09/2026, 7:33 AMRocky
04/09/2026, 7:33 AMsql
CREATE RESOURCE GROUP my_group
TO
(user='alice'),
(user='bob'),
(user='charlie')
WITH (
"cpu_weight" = "10",
"mem_limit" = "20%"
);
对现有资源组添加用户:
sql
ALTER RESOURCE GROUP my_group ADD (user='david');
──────────
2. 通过角色(Role)设置
如果你有一组用户,建议将他们归纳到一个 Role 中,然后在资源组分类器中指定该 `role`。这样,所有属于该角色的用户都会自动匹配到该资源组。
sql
-- 将分类器设置为匹配角色
CREATE RESOURCE GROUP role_group
TO
(role='analyst_role')
WITH (
"cpu_weight" = "50",
"mem_limit" = "30%"
);
──────────
3. 注意事项
* *匹配优先级*:如果一个用户既属于 user='alice' 的分类器,又属于 role='admin' 的分类器,StarRocks 会计算*匹配度(Degree of Matching)*。通常 user 的匹配权重比 role 更具体,匹配度更高。
* *查看匹配情况*:你可以通过 SHOW RESOURCE GROUPS ALL; 查看每个资源组下面挂载的所有分类器详情(包括 `user`、`role`、`ip` 等)。
* *DB 级设置*:你也可以通过 db 属性让多个用户在访问特定数据库时进入同一个资源组:`(db='sales_db')`。
总结: 虽然在一个括号(分类器)里 user 只能写一个字符串,但你可以写*无限个括号*,或者使用 Role 来批量管理用户。
参考文档
• administration/management/resource_management/resource_group.md
• sql-reference/sql-statements/cluster-management/resource_group/CREATE_RESOURCE_GROUP.md
References
• administration/user_privs/authorization/privilege_item.md
• administration/management/resource_management/resource_group.md
• sql-reference/sql-statements/cluster-management/resource_group/CREATE_RESOURCE_GROUP.md
• faq/resource_isolation_faq.md