Skip to main content

Performance Tuning

Overview​

PlantPulse performance improves only when bottlenecks in each layer, collection → processing → storage, are removed one by one. The key is not to blindly increase every value, but to monitor the metrics and tune only the bottleneck.

3 Tuning Principles

  1. Change one thing at a time: If you change multiple variables at once, you cannot determine which change had the effect.
  2. Base decisions on operational data: Reproduce actual traffic in a stage environment before making changes.
  3. Record everything: Document changed values and before/after metrics in your GitOps / operations wiki.
EnvironmentCPUMemoryDiskRecommended PIPELINE_THREADSRecommended PIPELINE_RATELIMIT
Development16 vCPU64 GBSSD1610,000 MPS
Standard32 vCPU128 GBNVMe3640,000 MPS
Large-scale48+ vCPU200+ GBNVMe64100,000 MPS

Key Tuning Variables Based on env.sh​

The variables most frequently adjusted in operational environments are managed in the host's bin/env.sh and compose/docker-compose.yml → Environment Variable Reference

VariableDefaultImpact
PP_CLUSTER_CORES30Spark / analytics core allocation
PP_CLUSTER_MEMORY_BY_CORE2GSpark executor memory/cores
PP_LANG / PP_TZko / Asia/SeoulJVM locale / timezone
JAVA_TOOL_OPTIONSAuto-generatedAutomatically applied to all child JVMs

For detailed variables, refer to the env.sh variable index in the Properties Reference.

Measurement Tools​

Tools for comparing before and after tuning:

cd /opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin

./status.sh # 모듈별 CPU / 메모리(PSS) 요약
./ops-check.sh # 헬스 + critical log
./memory-check.sh # 모듈별 메모리 상세
./memory-rank.sh # 메모리 순위
./pd node tpstats # Cassandra 스레드풀
./pd node compactionstats # Cassandra 컴팩션
./pd node table-stats # 테이블별 통계
./pd node proxyhistograms # Cassandra 지연 히스토그램

# Kafka consumer lag
./pd node topic

# JVM Heap / GC (컨테이너 진입 후)
./shell.sh
jcmd <pid> GC.heap_info
jcmd <pid> GC.heap_dump /tmp/heap.hprof

For external monitoring (Grafana / Prometheus), refer to the System Monitoring page.

Note: Optimal performance tuning values can vary depending on server specifications, data volume, and usage patterns. We recommend starting with the recommended settings below and adjusting gradually while monitoring the results.

Engine Pipeline Tuning​

Configuration file: plantpulse-server/config/plantpulse-engine.properties

Note: The engine pipeline is the critical path through which sensor-collected data is processed. These settings allow you to adjust the data processing speed and capacity.

Core Pipeline Parameters​

ParameterDefaultDescriptionTuning Guide
engine.pipeline.threads36Number of pipeline worker threadsRecommended 70–80% of host core count (48 cores in validation environment → 36)
engine.pipeline.ratelimit40000Maximum messages per second (MPS)Adjust according to server specifications
engine.pipeline.queue.size1200000Maximum pipeline queue sizeAdjust according to available memory
engine.pipeline.queue.o3.delay50Out-of-Order delay processing (ms)Adjust according to network latency
engine.pipeline.task.modeSINGLEPipeline task modeSINGLE or MULTI
engine.async.parallelism256Number of asynchronous parallel tasksRecommended 8–16 times the number of CPU cores

Streaming Settings​

ParameterDefaultDescription
engine.stream.processorDIRECTStream processing mode
engine.streaming.messaging.warning.ms5000Message delay warning threshold (ms)
engine.streaming.messaging.timeout.ms10000Message timeout (ms)
engine.streaming.messaging.timeout.store.typeFILE_QUEUETimeout message storage method
engine.streaming.messaging.timeout.recovery.typeDBTimeout recovery method

Worker Threads​

ParameterDefaultDescription
engine.job.thread.asset8Asset worker thread count
engine.job.thread.point8Point worker thread count

The table below shows recommended settings based on server specifications. Please refer to the column matching your operational environment's specifications.

ItemSmall-scale (8 cores/64GB)Medium-scale (16 cores/128GB)Large-scale (32 cores/256GB)
pipeline.threads163664
pipeline.ratelimit10,00040,000100,000
pipeline.queue.size300,0001,200,0003,000,000
async.parallelism64256512

Aster TSDB Tuning​

Configuration file: plantpulse-storage/db/cassandra/conf/cassandra.yaml

Note: Aster TSDB is the core database for storing time series data. As the data volume grows, Aster TSDB tuning has a significant impact on overall performance, so we recommend adjusting it for your operational environment.

Memory Settings​

ParameterDefaultDescription
memtable_heap_space2GiBMemtable heap memory
memtable_offheap_space2GiBMemtable off-heap memory
memtable_allocation_typeoffheap_objectsMemory allocation type
memtable_flush_writers8Memtable flush thread count

Concurrency Settings​

ParameterDefaultDescriptionTuning Guide
concurrent_reads256Concurrent read threadsRecommended disk count x 16
concurrent_writes256Concurrent write threadsRecommended CPU cores x 8
concurrent_counter_writes256Concurrent counter writesSet the same as concurrent_writes
concurrent_compactors8Concurrent compaction threadsRecommended 1/4 of CPU core count

Commit Log​

ParameterDefaultDescription
commitlog_syncperiodicSynchronous mode
commitlog_sync_period10000msSynchronous period
commitlog_segment_size320MiBSegment size
commitlog_total_space32GiBTotal commit log space

Timeouts​

ParameterDefaultDescription
read_request_timeout10000msRead timeout
write_request_timeout60000msWrite timeout
counter_write_request_timeout10000msCounter write timeout
cas_contention_timeout1000msCAS contention timeout
truncate_request_timeout600000msTruncate timeout

Compaction Strategy​

PlantPulse uses the UCS (Unified Compaction Strategy) designed for time series data characteristics.

Note: Compaction is the process by which Aster TSDB consolidates and merges data files (SSTables) stored on disk. Using an appropriate compaction strategy can save disk space and improve read performance.

storage.properties Settings:

ParameterDefaultDescription
storage.table.compaction.strategyUCSCompaction strategy (UCS or TWCS)
storage.table.compaction.strategy.ucs.scailing_parameterT8Scaling parameter
storage.table.compaction.strategy.ucs.min_sstable_size128MiBMinimum SSTable size
storage.table.compaction.strategy.ucs.target_sstable_size512MiBTarget SSTable size
storage.table.compaction.strategy.ucs.base_shard_count8Number of base shards
storage.table.compaction.strategy.ucs.max_sstables_to_compact6Maximum SSTables for compaction

Compression​

Uses ZStandard dictionary compression:

ParameterDefaultDescription
storage.compression.zstd.typeZstdDictionaryCompressorCompression method
storage.compression.zstd.level3Compression level (1–22; higher levels increase compression ratio but slow down speed)

TTL (Data Retention Period)​

Set the TTL for each table in storage.properties. Once the TTL expires, the corresponding data is automatically deleted, so set it according to your data retention requirements.

ParameterDefaultDescription
storage.tag.point.ttl62 (days)Tag point source data
storage.tag.point.map.ttl1 (days)Tag point map
storage.tag.point.sampling.ttl93 (days)Sampling data
storage.tag.point.snapshot.ttl93 (days)Snapshot data
storage.tag.point.aggregation.ttl93 (days)Aggregation data
storage.tag.point.archive.ttl365 (days)Archive data
storage.tag.blob.ttl93 (days)BLOB data
storage.asset.data.ttl10 (days)Asset data
storage.asset.data.sampling.ttl31 (days)Asset sampling data

Aster TSDB Performance Inspection Commands​

You can inspect the performance status of Aster TSDB using the following commands:

# 컴팩션 상태 확인
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node compactionstats

# 테이블별 통계 확인
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node table-stats

# 테이블 히스토그램 (읽기/쓰기 지연)
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node table-histograms

# SSTable 크기 확인
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node sstable-size

# 스레드풀 통계
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node tpstats

Spark Tuning​

Configuration file: plantpulse-analytics/spark/conf/spark-defaults.conf

Note: Apache Spark is a distributed processing engine for large-scale data analysis. Please refer to the settings below to improve the speed and stability of analytical jobs.

Resource Allocation​

ParameterDefaultDescription
spark.cores.max16Maximum Spark cores
spark.driver.cores2Driver core count
spark.driver.memory4gDriver memory
spark.executor.cores1Executor core count
spark.executor.memory2GExecutor memory
spark.executor.memoryOverhead2gExecutor overhead memory

Dynamic Allocation​

ParameterDefaultDescription
spark.dynamicAllocation.enabledtrueDynamic executor allocation
spark.dynamicAllocation.minExecutors2Minimum executor count
spark.dynamicAllocation.maxExecutors16Maximum executor count
spark.dynamicAllocation.executorIdleTimeout30Idle executor release time (seconds)

Shuffle and Parallelism​

ParameterDefaultDescription
spark.default.parallelism64Default parallelism
spark.sql.shuffle.partitions128SQL shuffle partition count
spark.sql.adaptive.enabledtrueAdaptive Query Execution
spark.sql.adaptive.coalescePartitions.enabledtrueAutomatic partition coalescing

JVM Settings​

Both Spark driver and executor use ZGC:

-XX:+UseZGC
-XX:+AlwaysPreTouch
-XX:+UseTLAB
-XX:+ResizeTLAB
-XX:+DisableExplicitGC

S3 (RustFS) Integration Settings​

ParameterDefaultDescription
spark.hadoop.fs.s3a.connection.maximum400Maximum S3 connections
spark.hadoop.fs.s3a.threads.max128Maximum S3 threads
spark.hadoop.fs.s3a.max.total.tasks1024Maximum async operations
spark.hadoop.fs.s3a.fast.uploadtrueFast upload enablement
spark.hadoop.fs.s3a.fast.upload.bufferdiskUpload buffer type
spark.hadoop.fs.s3a.block.size128MBS3 block size

Iceberg Settings​

ParameterDefaultDescription
spark.sql.iceberg.write.target-file-size-bytes256MBTarget file size
spark.sql.iceberg.column-stats.enabledtrueColumn statistics enablement
spark.sql.iceberg.vectorization.enabledtrueVectorized read enablement
spark.sql.iceberg.manifest.merge.enabledtrueManifest merging
spark.sql.parquet.compression.codeczstdParquet compression codec

Kafka Tuning​

Configuration file: plantpulse-messaging/kafka/config/server.properties

Note: Kafka is a message broker that delivers sensor data in real time. As data volume grows, you can adjust Kafka settings to improve processing performance.

Core Settings​

ParameterDefaultDescription
num.network.threads3Network processing threads
num.io.threads8I/O processing threads
socket.send.buffer.bytes102400Socket send buffer
socket.receive.buffer.bytes102400Socket receive buffer
socket.request.max.bytes104857600Maximum request size (100MB)
num.partitions1Default partition count
log.retention.hours168Log retention period (7 days)
log.segment.bytes1073741824Log segment size (1GB)

Tuning for High-Volume Processing​

If you process large volumes of IoT data, please refer to the settings below and adjust accordingly:

# 파티션 수 증가 (메시지 병렬 처리)
num.partitions=4

# I/O 스레드 증가
num.io.threads=16

# 네트워크 스레드 증가
num.network.threads=8

# 소켓 버퍼 증가
socket.send.buffer.bytes=1048576
socket.receive.buffer.bytes=1048576

Messaging Settings​

Configuration file: plantpulse-server/config/plantpulse-mq.properties

Kafka DDS Topics​

ParameterDefaultPurpose
mq.dds.kafka.topic.tag.pointpp-tag-pointTag point values
mq.dds.kafka.topic.tag.alarmpp-tag-alarmTag alarms
mq.dds.kafka.topic.asset.datapp-asset-dataAsset data
mq.dds.kafka.topic.asset.alarmpp-asset-alarmAsset alarms
mq.dds.kafka.topic.asset.eventpp-asset-eventAsset events
mq.dds.kafka.topic.asset.aggregationpp-asset-aggregationAsset aggregation
mq.dds.kafka.topic.domain.changed.eventpp-domain-changed-eventMetadata changes

MQTT DDS Topics​

ParameterDefaultPurpose
mq.dds.mqtt.topic.tag.pointtag/point/{tag_id}Point values per tag
mq.dds.mqtt.topic.tag.alarmtag/alarm/{tag_id}Alarms per tag
mq.dds.mqtt.topic.asset.dataasset/data/{asset_id}Data per asset
mq.dds.mqtt.topic.asset.commandasset/command/{asset_id}Asset control commands

Scheduler Settings​

Configuration file: quartz.properties (web app internal classpath resource — not a candidate for externalization)

ParameterDefaultDescription
org.quartz.threadPool.threadCount8Scheduler thread count
org.quartz.threadPool.threadPriority5Thread priority

Mail / Notification Settings​

Configuration location: PostgreSQL pp.mm_config table. On 2026-09-17, plantpulse-mail.properties was removed, and the path that read the old copy remaining in the external conf was also removed on 2026-09-18 — values enter only via the console or pp.mm_config. Key names and defaults remain unchanged.

ParameterDefaultDescription
mail.smtp.host192.168.0.41SMTP server address
mail.smtp.port25SMTP port
mail.smtp.authfalseAuthentication usage
mail.smtp.starttls.enablefalseTLS usage

Application Settings​

The application.properties file was removed in 2026.06. Console behavior settings such as theme and homepage are managed in the console's System > Settings Management (PostgreSQL mm_config table), and alarm.duplicate.check.minutes(duplicate alarm check interval, minutes) has been migrated to plantpulse-server/config/plantpulse-engine.properties.


Performance Bottleneck Diagnosis​

When performance issues occur, please refer to the diagnostic methods and solutions below for each symptom.

1. Pipeline Queue Backlog​

Symptoms: The pipeline wait queue persistently increases

# PlantPulse Dashboard 에서 "파이프라인 대기 큐" 패널을 확인해 주세요
# 또는 JMX: pipeline.queue.size 값을 확인해 주세요

Solutions:

  • Increase the engine.pipeline.threads value
  • Adjust the engine.pipeline.ratelimit value upward
  • Check Aster TSDB write performance

2. Aster TSDB Write Latency​

Symptoms: Write timeouts or WriteTimeoutException occur

# 컴팩션 상태 확인
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node compactionstats

# Memtable 플러시
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node flush

Solutions:

  • Increase the concurrent_writes value
  • Increase the compaction_throughput value
  • Check disk I/O performance (SSD usage is recommended)

3. Insufficient Memory​

Symptoms: Frequent JVM GC or OutOfMemoryError occurrences

Solutions:

  • In bin/start.sh of the service module, increase the -Xmx value
  • Reduce the engine.pipeline.queue.size value to conserve memory usage
  • Disable unnecessary caches

4. Network Latency​

Symptoms: Increased data reception delays (verifiable in the PlantPulse Dashboard "Network Latency" panel)

Solutions:

  • Check network status between the OPC server and PlantPulse
  • Adjust the engine.streaming.messaging.timeout.ms value
  • Check the MQTT QoS level

Technical Support​

For performance tuning inquiries: webmaster@kopens.com