Capacity planning
This guide helps you size Deephaven deployments for optimal performance based on workload characteristics, data volumes, and user requirements. Proper capacity planning ensures you provision adequate resources without over-provisioning, balancing performance and cost.
Note
This guide focuses on performance-oriented capacity planning. For high availability, disaster recovery, and resilience planning, see Resilience planning.
Capacity planning methodology
Effective capacity planning follows a structured approach:
- Define workload characteristics: Data volumes, query patterns, user concurrency
- Estimate resource requirements: CPU, memory, storage, network
- Validate with testing: Load test with representative workloads
- Plan for growth: Monitor trends and set scaling triggers
Define workload characteristics
Characterize your workload across these dimensions:
Data characteristics (aggregate across all tables):
- Ingest rate: Total rows per second across all tables
- Row size: Average bytes per row (varies by table)
- Table count: Number of actively ingested tables
- Data types: Proportion of numeric vs. string vs. complex types
- Retention: Days of intraday data before merging to historical
Query characteristics:
- Concurrent users: Users running queries and users viewing/subscribing to query results (each consumer adds load)
- Query complexity: Simple aggregations vs. complex joins vs. custom operations
- Active workers: Concurrent PQs and Code Studios per user
- Tracked rows: Rows tracked per active query
- Interactive vs. batch: Real-time dashboards vs. scheduled reports
Access patterns:
- Historical data access: Percentage of queries accessing historical vs. intraday data
- Data scanning: Typical date ranges queried (1 day, 1 week, 1 year)
- Update frequency: How often tables update (tick-by-tick, 1-second snapshots, etc.)
Estimate resource requirements
Use the following formulas as starting points, then validate with testing. The sections below cover CPU, memory, storage, and network sizing.
CPU capacity planning
Query host CPU sizing
Workers use all available CPUs on the host. When sizing a query host, estimate total cores needed:
Formula:
Components:
- Update parallelism: Varies by table complexity and update frequency
- Concurrent workers: Peak number of active workers on the host
- Background threads: Additional cores for updates, GC, and maintenance per worker
- Headroom: Reserve capacity for burst loads
Note
CPU requirements vary significantly based on query complexity, data types, and update frequency. There are no universal estimates — always validate with load testing using your specific workload.
See CPU optimization for tuning strategies.
DIS CPU sizing
Data Import Server (DIS):
DIS CPU requirements depend heavily on row complexity, column count, data transformations, and disk throughput.
To estimate your requirements:
- Deploy a test DIS with representative data schemas and ingestion rates.
- Measure CPU utilization under expected load.
- Scale based on observed utilization, leaving headroom for burst capacity.
Note
CPU requirements vary significantly by workload. There are no universal estimates — always validate with load testing using your specific data.
Memory capacity planning
Heap sizing
Heap sizing depends on query complexity, table sizes, and concurrent operations. Key factors include:
- Query working set: Tables actively being processed
- Table caches: Cached metadata and frequently accessed data
- Overhead: JVM internals, garbage collection headroom
Note
Memory usage varies significantly by data type (primitives: 8 bytes, strings: variable, objects: variable) and Deephaven's internal structures.
Starting point:
The default heap for new Code Studios and Persistent Queries is controlled by RemoteProcessingRequest.defaultQueryHeapMB. Check your environment's configured default and adjust based on workload.
How to adjust:
- Start a PQ or Code Studio with the default heap size.
- Run your typical workload and monitor heap usage using:
- The heap indicator in the Code Studio toolbar (shows current usage, free, and max).
- Or query
ProcessMetricsLogCoreV2for heap metrics:
- Increase heap if you see OOM errors or heap usage consistently near max after GC.
- Decrease heap if usage after GC is consistently below 50% (frees resources for other workers).
See Controlling query worker heap size for configuration details.
Direct memory sizing: When using direct memory for data buffers, the data buffer pool can be configured up to 2× heap size. Size -XX:MaxDirectMemorySize to accommodate the data buffer pool plus overhead for network buffers.
System memory sizing
Formula:
Any RAM not used by processes becomes available to the OS page cache, improving I/O performance. Leave headroom beyond process requirements to benefit from caching.
Example:
- Heap: 32 GB
- Direct memory: 16 GB
- OS overhead: 8 GB
- Minimum system RAM: 56 GB → provision 64 GB or more
The extra ~8 GB becomes available for OS page cache.
See Memory management for tuning strategies.
Storage capacity planning
Storage capacity sizing
Intraday storage:
Note
The growth factor, compression ratios, and overhead multipliers in these examples are illustrative only. Actual values vary significantly based on your data characteristics, storage format, and access patterns. Always measure with representative data to determine accurate sizing for your environment.
Example (illustrative): 100 GB/day × 3 days × 1.5 (growth factor) = 450 GB per namespace
Historical storage:
Compression ratios vary widely based on data characteristics (cardinality, repetition, data types). As a rough guide:
- Deephaven native: ~1.0× (uncompressed)
- Parquet SNAPPY: 0.3× to 0.5× typical, but can range from 0.1× (highly compressible) to 0.8× (low cardinality strings, random data)
Example (illustrative): 100 GB/day × 365 days × 0.4 (compression) × 1.2 (overhead) = 17.5 TB
Storage performance sizing
IOPS and throughput requirements vary significantly based on:
- Data ingestion rate: Higher row rates require more write IOPS/throughput.
- Query patterns: Concurrent queries increase read demands.
- Column count and types: Wide tables with strings require more I/O than narrow numeric tables.
- Merge workloads: Merge operations require sustained read+write throughput.
To estimate your requirements:
- Measure baseline I/O with representative test data using tools like
iostatoriotop. - Scale estimates based on expected production data volumes.
- Add headroom (20-30%) for burst capacity.
See Storage tuning for optimization strategies.
Network capacity planning
Network traffic sources
Network bandwidth requirements depend on the sum of all traffic sources:
- Data ingestion: Inbound data from external sources (Kafka, binary logs, etc.)
- TDCP traffic: Data served to workers via TDCP from DIS
- NFS/S3 storage: Historical data access over network-attached storage
- etcd: Cluster coordination traffic (frequent small packets)
- Inter-process communication: Controller, dispatchers, workers, web services
To estimate requirements:
- Measure baseline traffic with tools like
iftop,nethogs, or switch port statistics. - Identify peak periods (market open, batch jobs, etc.).
- Add headroom (2-3×) for burst capacity.
Note
Network requirements vary significantly by deployment. Measure actual traffic patterns rather than relying on estimates.
Validation and testing
Capacity testing procedure
-
Load test with synthetic data:
- Generate representative data volumes and schemas.
- Simulate peak concurrent user load.
- Measure resource utilization (CPU, memory, I/O, network).
-
Identify bottlenecks:
- Which resource reaches capacity first?
- What is headroom at peak load?
- Are there queuing delays or timeouts?
-
Measure key metrics:
- Query response time (p50, p95, p99) — see
QueryPerformanceLogCoreV2 - Data ingestion lag
- GC pause times and frequency
- Storage I/O wait
- Network utilization
- Query response time (p50, p95, p99) — see
-
Adjust and retest:
- Increase constrained resources.
- Validate improvement.
- Test edge cases (burst load, data spikes).
Capacity headroom guidelines
Maintain headroom for growth and burst capacity.
How to establish headroom:
- Measure baseline utilization during normal and peak operations:
- CPU:
htoportop - Memory:
free -hand heap metrics fromProcessMetricsLogCoreV2 - Storage:
iostat -xz 5 - Network:
iftopor switch port statistics
- CPU:
- Note your typical peak — this becomes your baseline.
- Plan to scale when sustained utilization consistently exceeds your baseline with limited headroom for bursts.
Growth planning
Scaling triggers
Plan to scale when you observe:
- CPU: Sustained high utilization during peak hours relative to your baseline
- Memory: Frequent full GC cycles, growing GC pause times, or OOM errors
- Storage: Sustained high I/O utilization or nearing capacity
- Network: Sustained high utilization or increasing latency
Scaling strategies
| Strategy | Pros | Cons |
|---|---|---|
| Vertical (scale up) | Simpler, better for single-worker loads | Hardware limits, requires downtime |
| Horizontal (scale out) | Near-unlimited scaling, incremental | More complex, requires load balancing |
Quick reference checklist
- ✅ Define workload: Data ingestion rate, concurrent users, query patterns
- ✅ Estimate CPU: Host cores based on query parallelism and concurrency
- ✅ Estimate memory: Heap and direct memory based on working set size
- ✅ Estimate storage: Capacity (intraday + historical) and performance
- ✅ Estimate network: Bandwidth for ingestion, queries, and storage access
- ✅ Validate with testing: Load test with representative workload
- ✅ Measure headroom: Ensure 20-40% capacity above peak load
- ✅ Plan for growth: Monitor trends and set scaling triggers