Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
9d490f5
Disabled some benchmarks and scaled
stanbrub Mar 13, 2026
47f066f
Scaled up basic math combo
stanbrub Mar 13, 2026
dea74d7
Merge branch 'deephaven:main' into gc-benchmarking
stanbrub Mar 19, 2026
15cf1f4
Added a Local Parquet Generator as opposed to going through Kafka
stanbrub Mar 20, 2026
8604111
Added local parquet generator and 1st training test
stanbrub Mar 24, 2026
83b1c11
Added more train benchmarks. Improved Local Parquet Generator
stanbrub Mar 25, 2026
c552c01
Revert BasicMathCombo
stanbrub Mar 26, 2026
62aa96a
Revert BasicMathCombo
stanbrub Mar 26, 2026
f78ca22
Reverted scale and disabled for pre-train standard tests used for pre…
stanbrub Mar 26, 2026
e5412e7
Parallelized local parquet. worked around directory link failures
stanbrub Mar 31, 2026
ff4d891
Added 1st pass at benchmark even retrieval with JFR
stanbrub Apr 1, 2026
f35ab4f
Merge branch 'deephaven:main' into gc-benchmarking
stanbrub Apr 7, 2026
25629cc
Added jfr events
stanbrub Apr 7, 2026
254cca0
Merge branch 'deephaven:main' into gc-benchmarking
stanbrub Apr 7, 2026
528c365
Added UGP events
stanbrub Apr 9, 2026
bd5ff02
Rescaled only static trained for 120 secs
stanbrub Apr 10, 2026
75449bb
Updated adhoc for local parquet env variables
stanbrub Apr 10, 2026
ec2d95e
Open up dh data dir so local parquet can work
stanbrub Apr 10, 2026
a402a54
More logging for benchmark runs
stanbrub Apr 10, 2026
4cf8357
Scaling back AggBy because of system lockup
stanbrub Apr 10, 2026
8507794
Restrict the number of parquet threads and memory for the runner
stanbrub Apr 10, 2026
c0b5e7a
Fixed NaturalJoin OOM
stanbrub Apr 11, 2026
8f1a77f
Added separate scalling for static vs inc
stanbrub Apr 22, 2026
2938992
Better separation for running static and inc. Added ugp deltas
stanbrub Apr 23, 2026
9b326e0
turn on JFR metrics
stanbrub Apr 23, 2026
7fe14cc
Turn off Inc runs
stanbrub Apr 23, 2026
5e1d59c
Added ss_log budget metric
stanbrub May 5, 2026
a1316d4
Added runner setting for auto tune cycle factor
stanbrub May 6, 2026
af3d82b
G1 inc release max
stanbrub May 15, 2026
28745a8
ParallelGC inc release max
stanbrub May 16, 2026
ac0c87f
Shenandoah GC inc release max
stanbrub May 16, 2026
9d630d9
ZGC inc release max
stanbrub May 16, 2026
dfa44df
Inc release filter min
stanbrub May 17, 2026
3ab1845
Updated for 100ms cycle at 90% min
stanbrub May 21, 2026
e0e763f
Added state log ugp times
stanbrub May 28, 2026
4fd604a
Pared down to two Filter/Nat tests
stanbrub May 28, 2026
07eacdf
Scaled for 1 sec cycles
stanbrub May 29, 2026
90e7153
Set autotune to 90% target release
stanbrub Jun 1, 2026
f18c994
User JVM 25 for adhoc
stanbrub Jun 2, 2026
8240602
Added update listener cycle times instead of server state log ones
stanbrub Jun 3, 2026
9951735
Set 20% inc release
stanbrub Jun 3, 2026
7c18a2c
Change inc release to 40%
stanbrub Jun 3, 2026
ce992b3
Change inc release to 60%
stanbrub Jun 4, 2026
fcde3fa
Change inc release to 80%
stanbrub Jun 4, 2026
ff2795a
Change inc release to 100%
stanbrub Jun 4, 2026
60839de
Run 50ms against zfc
stanbrub Jun 4, 2026
d18049c
Make release filter table smaller based on inc release factor
stanbrub Jun 4, 2026
c43719a
Change inc release to 40%
stanbrub Jun 4, 2026
45d5314
Change inc release to 20%
stanbrub Jun 4, 2026
36b1e83
Change inc release to 40%
stanbrub Jun 4, 2026
d4e0255
Change inc release to 60%
stanbrub Jun 4, 2026
1b351a5
Change inc release to 80%
stanbrub Jun 4, 2026
4f4124a
Change inc release to 100%
stanbrub Jun 5, 2026
11dbba7
Scale for Java 25
stanbrub Jun 5, 2026
c048170
Roll back changes some unwanted changes
stanbrub Jun 5, 2026
c9af58a
Switch to java 17
stanbrub Jun 8, 2026
5364601
Change to JVM 25
stanbrub Jun 9, 2026
4af7393
Rescaled for 100ms benchmarks
stanbrub Jun 10, 2026
920c89c
Changed autotune to 90% for testing
stanbrub Jun 10, 2026
37dc336
Add 1.10% inc target
stanbrub Jun 11, 2026
c6f4a00
Turn off static for now. Do inc 100p
stanbrub Jun 12, 2026
e29b3bb
Do huge mem options for 1 sec
stanbrub Jun 17, 2026
83f4c78
Doing Just Inc for 80% throughput now
stanbrub Jun 18, 2026
6837afa
Doing JVM 17 with p1.0 inc and static
stanbrub Jun 22, 2026
e093003
Scale updateBy for 1sec cycles
stanbrub Jun 23, 2026
11f7985
Added sleep for slow DH startups
stanbrub Jun 23, 2026
7ed69b6
Yet more waiting for ZGC
stanbrub Jun 23, 2026
f68564d
More p90 100ms j25 huge benchmarks
stanbrub Jun 24, 2026
0f5c61c
1st try at GC report
stanbrub Jun 24, 2026
d580534
Reformatted summary tables
stanbrub Jun 25, 2026
390f019
Fixed static names
stanbrub Jun 25, 2026
8989a84
Fixed png names
stanbrub Jun 25, 2026
dd15089
Fixed inc memory leak. Made train dashboard.
stanbrub Jun 30, 2026
758520f
Copyright updates
stanbrub Jun 30, 2026
3b9293b
Got train dashboard working against GCloud with csvs pulled up into p…
stanbrub Jul 2, 2026
1f092aa
Added all gc rankings tables
stanbrub Jul 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/resources/adhoc-benchmark-docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
services:
deephaven:
image: ${DOCKER_IMG}
image: ghcr.io/stanbrub/server:jvm25
ports:
- "${DEEPHAVEN_PORT:-10000}:10000"
volumes:
- ./data:/data
- ./minio:/minio
environment:
- "JAVA_OPTS=-XX:+UseG1GC"
- "START_OPTS=-DAuthHandlers=io.deephaven.auth.AnonymousAuthenticationHandler ${CONFIG_OPTS}"
- "DEEPHAVEN_HOST_OS_DIR=${ENV_DEEPHAVEN_HOST_OS_DIR}"

redpanda:
command:
Expand Down
2 changes: 1 addition & 1 deletion .github/resources/adhoc-scale-benchmark.properties
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ schema.registry.addr=redpanda:8081
kafka.consumer.addr=redpanda:29092

# Default timeout to complete processes (Executing queries, generating records)
default.completion.timeout=10 minutes
default.completion.timeout=20 minutes

# Default data distribution for column data (random, ascending, descending, runlength)
default.data.distribution=${baseDistrib}
Expand Down
1 change: 1 addition & 0 deletions .github/scripts/build-benchmark-artifact-remote.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ title "- Building Remote Benchmark Artifact on ${HOST} -"

title "-- Building and Verifying --"
cd ${GIT_DIR}
sleep 10 # Some JVM command lines start DH slower than others
mvn verify

title "-- Cleanup After Build --"
Expand Down
1 change: 1 addition & 0 deletions .github/scripts/manage-deephaven-remote.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ if [[ ${CONFIG_OPTS} == "<default>" ]]; then
CONFIG_OPTS="-Xmx24g"
fi
echo "CONFIG_OPTS=${CONFIG_OPTS}" > .env
echo "ENV_DEEPHAVEN_HOST_OS_DIR=${DEEPHAVEN_DIR}" >> .env

IS_BRANCH="false"
if [[ ${DOCKER_IMG} == *"@sha"*":"* ]]; then
Expand Down
2 changes: 1 addition & 1 deletion .github/scripts/run-benchmarks-remote.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ title "-- Running Benchmarks --"
set +f
cd ${RUN_DIR}
cat ${RUN_TYPE}-scale-benchmark.properties | sed 's|${baseRowCount}|'"${ROW_COUNT}|g" | sed 's|${baseDistrib}|'"${DISTRIB}|g" | sed 's|${userHome}|'"${HOME}|g" > scale-benchmark.properties
JAVA_OPTS=$(echo -Dbenchmark.profile=scale-benchmark.properties -jar deephaven-benchmark-*-standalone.jar -cp standard-tests.jar)
JAVA_OPTS=$(echo -Xmx4g -Dbenchmark.profile=scale-benchmark.properties -jar deephaven-benchmark-*-standalone.jar -cp standard-tests.jar)
set -f

if [ "${TAG_NAME}" = "Any" ]; then
Expand Down
3 changes: 2 additions & 1 deletion .github/scripts/setup-test-server-remote.sh
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ sudo docker system prune --volumes --force
sudo rm -rf ${DEEPHAVEN_DIR}

title "-- Staging Docker Resources --"
mkdir -p ${DEEPHAVEN_DIR}
mkdir -p ${DEEPHAVEN_DIR}/data
chmod 777 ${DEEPHAVEN_DIR}/data
cd ${DEEPHAVEN_DIR}
cp ${GIT_DIR}/benchmark/.github/resources/${RUN_TYPE}-benchmark-docker-compose.yml docker-compose.yml

Expand Down
Binary file added docs/gc/all-gc-rankings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
138 changes: 138 additions & 0 deletions docs/gc/gc-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Overview

This report provides some insight into how various Deephaven CE operations behave with different Garbage Collectors and settings. It is not possible to test every combination of JVM version, GC option, heap size, data size/cardinality, DHC operation, OS, and hardware platform. What follows are results based on a small subset of the possibilities. Each user will have a different setup, but hopefully we can glean some useful tips from the data that has been collected.

We are covering only JVM 17 and JVM 25. This presents an interesting challenge, because GC options have changed dramatically in the four years in between. For example, ZGC generational didn't exist in JVM 17, while ZGC non-generational doesn't exist in JVM 25. The approach taken here was to use the options that will likely be the defaults in JVM 25+ and then try to use the nearest approximation in JVM 17.

One other thing to note is that, judging by recent JDK release notes, the strategy for GCs going forward is to make GCs more self-tuning. Since the GC's top priority is keeping the application running, the GC can override user-supplied settings if it needs to. The JVM options used for this effort are intentionally minimal and tend to rely more on defaults.

## TL;DR

Here are some highlights from the data:
- For best Static throughput, use G1 or G1 THP. (Others degrade by 4% to 22%)
- For best Ticking throughput, use G1, but expect higher jitter. (5% to 12% more)
- For lowest jitter, use Shenandoah, though it's lower throughput than G1. (9% to 15% less)
- For best 100ms cycle throughput-jitter combo, use Shenandoah THP (3rd-5th best throughput, best jitter)
- For best 1sec cycle combo of throughput and jitter, use G1 THP (best throughput, 3rd best jitter)

## The Benchmarks

The benchmarks used for this effort are not the nightly benchmarks, which run single operations typically for 8-10 seconds. Instead a longer running and smaller benchmark set is used that covers categories of operations. This set typically runs for 1.5 mins to 2 mins, lazily reading from a large parquet file. The idea is to use few benchmarks to cover much of the operational code base. These are referred to as "Training Benchmarks".

- AggBy: Runs multiple mathematical operations like avg, std, var, min, max, etc
- Filter: Runs `where_in` and `where` filters
- Formula: Runs multiple UDFs and Inline Formulas
- NaturalJoin: Runs a natural join operation
- Ordered: Runs multiple aggBy ordered operations like median, unique, sorted_first, etc
- UpdateBy: Runs multiple windowed operations

## Naming Conventions

The set names for the various runs use a naming convention like `<gc-type>_<cycle-time>_<autotune-load>_<jvm>[_<extra>]`
- gc-type: `g1gc`, `shen`, `zgc`, `para`
- cycle-time: `1000` (1sec), `100` (100ms)
- autotune-load: `p80`, `p90`, `p100`, `p110` (Percentage throughput targets)
- extra: `huge` (Transparent Huge Pages)

## Supporting Evidence for TL;DR

What follows are charts showing the results of many benchmarks runs using various options. The naming convention for the gc sets displayed have been described previously. First, there are three kinds of summary tables; throughput, jitter, on-budget. There is also a table that combines all three.
- Throughput: Starting with rows/sec, a normalized fraction starting from 1. So 1.20 would be 20% faster than 1.0.
- Jitter: Starting with Coefficient of Variation, a normalized fraction starting from 1. So 1.04 would be 4% more jitter than 1.0.
- On Budget: A percentage a cycles that finished on or below the cycle time (e.g. 1000ms or 100ms)

## Overall Rankings

Overall ranking can show the distance between the overall throughput, jitter, or on-budget metrics for each GC for the same set of configuration. For example, on JVM 25 for Static data, ZGC is 16% slower than G1.

![All GC Rankings](./all-gc-rankings.png)

### Static Data Throughput

The following chart shows Throughput for Static data for JVM 17. G1 comes in first with ZGC a surprising second.
![Static Throughput for JVM 17](./static-j17.throughput.png)

The following chart shows Throughput for Static data for JVM 25. The story is similar to JVM 17 with G1 in front but followed by parallel GC.
![Static Throughput for JVM 25](./static-j25.throughput.png)

### Ticking Data Throughput

There are three considerations captured here; throughput, jitter, and on-budget percentage. These can be weighted based on the needs of the workflow. Typically, but not always, higher throughput means higher jitter or lower on-budget percentage.

The following chart shows throughput for JVM 17 with 1s UGP cycles.
![Ticking Throughput for JVM 17 1s](./inc-j17-1s.throughput.png)

The following chart shows throughput for JVM 25 with 1s UGP cycles.
![Ticking Throughput for JVM 25 1s](./inc-j25-1s.throughput.png)

The following charts show summaries of JVM 17 and JVM 25 with three factors organized according to their ranks for the benchmarks overall. For example, the values in the "jitter" column are the geometric means for each "gc_type" set when compare to every other set in the table. This gives a ranking of each column that can provide a quicker comparison than a dozen individual tables.

<table><tr>
<td><img src="./inc-j17-1s.summary.png" alt="GC Summary for JVM 17 1s"></td>
<td><img src="./inc-j25-1s.summary.png" alt="GC Summary for JVM 25 1s"></td>
</tr></table>

The following charts show summaries of JVM 25 for 100ms running at an autotune target of 80%, 90%, and 100%

<table><tr>
<td><img src="./inc-j25-100ms-p80.summary.png" alt="GC Summary 100ms p80"></td>
<td><img src="./inc-j25-100ms-p90.summary.png" alt="GC Summary 100ms p90"></td>
<td><img src="./inc-j25-100ms-p100.summary.png" alt="GC Summary 100ms p100"></td>
</tr></table>

## Test Setup

- OS: Ubuntu 24.04
- Hardware: Intel(R) Xeon(R) E-2388G (8C/16T), 64G DDR4-3200, NVME drive
- OS Settings: THPMode=madvise, CPUPower=schedutil, ASLR=disabled
- Java: 48G Heap, Temurin 17 and 25
- Container: Docker Images built from a recent edge build
- Test Iterations: 7
- Static Data Provider: Parquet
- Ticking Data Provider: Autotuning Incremental Release Filter from Parquet

## JVM Options

The strategy for the JVM options selected for each JVM (e.g. 17, 25) was to make them equivalent. Of course, this was impossible, because different options are supported in different versions of the same GC. For the JVM 25 options, an attempt was made to use options that will be the defaults in future versions of the JVM.

The JVM options used for these benchmarks are as follows:
- All GCs: `-Xms48g -Xmx48g -XX:+UseStringDeduplication -DPeriodicUpdateGraph.targetCycleDurationMillis=<100 or 1000>`
- Huge: `-XX:+AlwaysPreTouch -XX:+UseTransparentHugePages`
- JDK 17
- G1GC: `-XX:+UseG1GC -XX:G1HeapRegionSize=32m -XX:+G1UseAdaptiveIHOP`
- ParallelGC: `-XX:+UseParallelGC -XX:ParallelGCThreads=13 `
- Shenandoah: `-XX:+UseShenandoahGC -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahImplicitGCInvokesConcurrent`
- ZGC: `-XX:+UseZGC -XX:ConcGCThreads=6`
- JDK 25
- G1GC: `-XX:+UseG1GC -XX:+UseCompactObjectHeaders`
- ParallelGC: `-XX:+UseParallelGC -XX:+UseCompactObjectHeaders`
- Shenandoah: `-XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational -XX:+UseCompactObjectHeaders`
- ZGC: `-XX:+UseZGC -XX:+UseCompactObjectHeaders`

### What are Huge Memory Pages?

All of the benchmarks sets that end with "_huge" have the options `-XX:+AlwaysPreTouch -XX:+UseTransparentHugePages`. In a nutshell, these options pair well together to initialize huge memory pages (e.g. 2MB) at JVM init. This provides better memory performance for larger heaps (> 8G) but can suffer from larger startup costs. In these benchmarks THP provided sizable throughput increases for some benchmarks like natural join in exchange for a small increase in jitter.

What about `-XX:+UseLargePages`? These have not been tested but could provide similar benefits as THP but with a faster JVM startup time, since they are preallocated during OS start. This requires strict rules, however, and is best for systems that are locked down in terms of memory configuration. It is tricky to size as well, since it is used for more than just JVM heap, and that depends on JVM version.

### What are Compact Headers?

The `-XX:+UseCompactObjectHeaders` option cuts the Java Object header in half (16 to 8 bytes) to reduce object footprint and improve cache utilization. Systems that use lots of small objects can benefit with better throughput. Minimal testing for Deephaven showed no significant change in performance, but the option will be a default in JVM 26+.

## Needed for Further Investigation

In order to improve investigations like this one, we need much more information on how customers are using Deephaven. Without violating any NDA, we should be able to produce the following:

- Query structure and complexity like a flow chart for the table chains
- General order of operations. Do they filter first, then agg, then sort?
- Static and ticking schema width, column types, and value cardinality
- Complexity of inline formulas and UDFs
- Type of hardware and containerization
- Java heap and cpu thread count typically used
- Where the data typically comes from. DHE live tables? Kafka? Parquet?
- What JVM options have already been tried in the field





Binary file added docs/gc/inc-j17-1s.summary.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/gc/inc-j17-1s.throughput.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/gc/inc-j25-100ms-p100.summary.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/gc/inc-j25-100ms-p80.summary.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/gc/inc-j25-100ms-p90.summary.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/gc/inc-j25-1s.summary.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/gc/inc-j25-1s.throughput.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/gc/static-j17.throughput.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/gc/static-j25.throughput.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 6 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@
<file>${project.basedir}/eclipse-java-google-style.xml</file>
</eclipse>
<licenseHeader>
<content>/* Copyright (c) 2022-$YEAR Deephaven Data Labs and Patent Pending */</content>
<content>/* Copyright (c) $YEAR Deephaven Data Labs and Patent Pending */</content>
</licenseHeader>
</java>
</configuration>
Expand Down Expand Up @@ -271,6 +271,11 @@
<artifactId>kafka-protobuf-serializer</artifactId>
<version>8.1.1</version>
</dependency>
<dependency>
<groupId>blue.strategic.parquet</groupId>
<artifactId>parquet-floor</artifactId>
<version>1.64</version>
</dependency>
<dependency>
<groupId>io.deephaven</groupId>
<artifactId>deephaven-java-client-barrage-dagger</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
* practical purposes, though it is not ideal.
*/
public class CompareTestRunner {
static {
System.setProperty("root.test.package", "io.deephaven.benchmark.tests");
}
final Object testInst;
final Set<String> requiredPackages = new LinkedHashSet<>();
final Map<String, String> downloadFiles = new LinkedHashMap<>();
Expand Down
Loading
Loading