Kailas Unni
05/17/2026, 7:03 AMRocky
05/17/2026, 7:04 AMcompact_threads | BE | 1 or 2 | Tradeoff: Slower merging of data version (tablets). If set too low, you may see "too many versions" errors if ingestion is high.
max_compaction_concurrency | BE | 2 | Tradeoff: Limits total parallel compaction tasks. Prevents CPU spikes but can lead to a backlog of uncompacted data.
update_compaction_num_threads_per_disk | BE | 1 | Tradeoff: Specifically throttles compaction for Primary Key tables. Essential if your routine load targets PK tables.
2. Throttle Routine Load Ingestion
The default concurrency for Routine Load assumes a much larger BE. You must reduce the task pressure to match your 2-core limit.
Config Key | Location | Recommended Value | Tradeoff
max_routine_load_task_num_per_be | FE | 2 to 4 | Tradeoff: Lowering this reduces CPU usage but limits total ingestion throughput. At 3.5k rows/sec, 4 tasks should suffice.
max_routine_load_task_concurrent_num | FE | 2 | Tradeoff: Limits how many tasks a single job can spawn. Helps prevent one high-traffic topic from hogging all BE threads.
routine_load_task_consume_second | FE/Job | 20 - 30 | Tradeoff: Longer tasks reduce the frequency of "commit" overhead, but increase the latency before data is visible in queries.
3. Manage Routine Load Error Rows
"Error row buildup" usually means your max_error_number is high enough that the job keeps running despite bad data, or you are not seeing why rows are failing.
* Surface Errors: Set log_rejected_record_num to a positive value (e.g., 100) in your BE config. This allows you to see the actual failed rows via information_schema.loads.
* Job Tuning: In your CREATE ROUTINE LOAD statement, use these properties:
* `"max_error_number" = "100"`: If more than 100 errors occur in a window, the job pauses. This prevents the FE from being flooded with error metadata.
_ `"max_batch_rows" = "200000"`: This defines the error window. Errors are calculated as a ratio within 10 _ max_batch_rows.
4. Optimize for 2-Core K8s Environment
StarRocks' default thread pools are too large for a 2-core pod. Manually cap these to prevent the BE from thrashing.
Config Key | Location | Recommended Value | Why?
num_cores | BE | 2 | Explicitly tells the BE to optimize internal scheduling for 2 cores.
scanner_thread_pool_thread_num | BE | 8 (Default 48) | Reduces context switching during data scans.
pipeline_prepare_thread_pool_thread_num | BE | 2 | Matches physical core count for query preparation.
fragment_pool_thread_num_min | BE | 2 (Default 64) | Prevents the BE from pre-allocating dozens of idle threads.
Summary Recommendation
1. Lower Compaction: Set compact_threads = 1 and max_compaction_concurrency = 2 on all BEs.
2. Lower Ingestion Concurrency: Run ADMIN SET FRONTEND CONFIG ("max_routine_load_task_num_per_be" = "4"); on the FE.
3. Monitor Versions: If you see OLAP_ERR_TOO_MANY_VERIONS after these changes, you must either increase CPU cores per pod or reduce the Kafka ingestion frequency by increasing max_batch_interval intervals.
References
• administration/management/BE_configuration.md
• faq/Others.mdRocky
05/17/2026, 7:04 AMHarsh
05/17/2026, 7:41 AM