CPU optimization

This guide covers strategies for optimizing CPU performance in your Deephaven cluster through proper resource allocation, JVM tuning, and concurrency configuration.

Note

For query-level optimization (writing efficient queries), see Monitor queries.

Understanding CPU usage in Deephaven

Deephaven is a compute-intensive system that relies heavily on CPU resources for data processing, query evaluation, and real-time updates.

Application processes vs. worker processes

Deephaven distributes CPU load across different process types:

  • Application processes include the Controller, Query Dispatchers, Data Import Server, and Web API Service. These coordinate work but typically have modest CPU requirements.
  • Worker processes execute user queries, table operations, and update cycles. These are usually the primary CPU consumers.

Query types and CPU patterns

Different query workloads exhibit distinct CPU characteristics:

  • Real-time ticking queries: Continuous CPU usage during update cycles as new data arrives.
  • Large batch/historical queries: High CPU bursts during initial computation, followed by minimal CPU when results are cached.
  • Interactive queries: Sporadic CPU usage tied to user actions like sorting, filtering, or chart interactions.

JIT compilation

The JVM uses Just-In-Time (JIT) compilation to optimize frequently-executed code paths:

  • Warm-up period: During initial execution, the JIT compiler analyzes code and compiles hot paths to native code, causing higher CPU usage temporarily.
  • Steady state: After warm-up, compiled code executes more efficiently.
  • Compilation threads: The JIT compiler uses dedicated threads (controlled by -XX:CICompilerCount) that consume CPU during compilation.

You can control JIT compiler thread count using remote processing profiles.

Identifying CPU bottlenecks

Using htop to identify high-CPU processes

Key metrics to observe:

  • Process CPU %: Individual process utilization
  • Load averages: System-wide CPU load over 1, 5, and 15 minutes
  • CPU bar colors: User processes (green), system/kernel (red), I/O wait (blue)

To identify specific Deephaven processes:

For Kubernetes deployments:

Analyzing thread dumps

Thread dumps reveal what each thread in a Java process is doing. Use jstack to capture:

For CPU analysis, capture multiple (3-5) thread dumps spaced 5-10 seconds apart to identify consistently active threads.

Thread states relevant to CPU analysis:

  • RUNNABLE — Thread is executing on CPU or ready to execute.
  • BLOCKED — Thread is waiting to acquire a lock.
  • WAITING/TIMED_WAITING — Thread is parked or waiting.

What to look for:

  • Hot threads: Same thread ID in RUNNABLE across multiple dumps
  • Hot methods: Same method appearing repeatedly in stack traces
  • Thread pool saturation: All threads in a pool executing simultaneously

See Troubleshoot Java processes for additional techniques.

Monitoring internal performance tables

Deephaven's internal tables provide CPU-related metrics:

Key tables for CPU analysis:

TablePurpose
QueryPerformanceLogCoreV2Query-level CPU metrics (CpuNanos, UserCpuNanos)
QueryOperationPerformanceLogCoreV2Per-operation CPU metrics
UpdatePerformanceLogCoreV2Update cycle CPU metrics

Tip

Compare CpuNanos to UsageNanos. If CpuNanos is close to UsageNanos, the operation is CPU-bound. If CpuNanos is much smaller, it's likely I/O-bound or waiting on resources.

CPU tuning strategies

Resource allocation

Kubernetes CPU configuration

For Kubernetes deployments, configure CPU requests and limits in your Helm values file. See Kubernetes configuration settings.

Worker CPU allocation is specified when creating a Persistent Query under Advanced SettingsCPU Shares.

Bare-metal and VM deployments

For non-Kubernetes deployments, manage CPU allocation through process scheduling and resource limits.

Standard Linux tools (cgroups, nice/renice) apply to Deephaven processes as with any JVM workload.

JVM tuning

Garbage collection tuning

GC parallelism can be tuned to balance CPU overhead against collection efficiency:

  • ParallelGCThreads — Threads used during stop-the-world GC phases
  • ConcGCThreads — Threads used for concurrent marking (typically 1/4 of ParallelGCThreads)

See Memory management for comprehensive GC configuration.

JIT compiler optimization

Control JIT compiler threads via remote processing profiles:

Default: The default value for RemoteProcessingRequestProfile.JitCompilerCount is 2.

When to adjust:

  • Reduce to 1 if you observe high CPU during worker startup or have limited cores per worker.
  • Increase to 3-4 if workers with large heaps need faster warm-up and you have CPU headroom.

If this property is removed entirely from the configuration, the JVM's built-in default applies instead. See Remote processing profiles for details.

Concurrency settings

Persistent Query startup pool

The Controller uses a thread pool to start Persistent Queries:

Increase to start more PQs concurrently when many are scheduled to start at the same time. See PQ Controller.

Dispatcher concurrent startups

Each dispatcher limits how many workers it starts simultaneously:

Increase to allow more workers to start concurrently on a single dispatcher. See Query Dispatcher configuration.

Quick reference

JVM parameters

ParameterPurposeNotes
-XX:+UseG1GCEnable G1 GCRecommended for Java 11+
-XX:ParallelGCThreadsFull GC parallelismTune based on available cores
-XX:ConcGCThreadsConcurrent GC threadsTune based on GC behavior
-XX:CICompilerCountJIT compiler threadsDefault: 2 via remote processing profile
-XX:+UseNUMANUMA awarenessEnable on multi-socket systems

CPU utilization monitoring

Appropriate CPU utilization targets are system-dependent.

To establish and monitor your baseline:

  1. Run htop or top during typical operations and note average CPU usage
  2. Query ProcessMetricsLogCoreV2 for CPU metrics over time:
  3. Set alerts when sustained utilization exceeds your observed normal range
  4. For VMs, check steal in top — high steal indicates host contention

Troubleshooting quick checks

SymptomLikely causeAction
High CPU, slow queriesInefficient queryCheck query logs, profiler
100% CPU, no progressGC thrashingCheck heap, GC logs
Unbalanced core usageThread contentionCapture thread dump
High CPU at startupToo many JIT threadsReduce CICompilerCount