ZGC for Cassandra
ZGC performs marking, relocation and reference processing on threads that run alongside the application. Only short stop-the-world phases remain, and their cost follows the number of references the collector must scan while threads are stopped rather than the amount of live data on the heap.
No released Cassandra version configures ZGC. The collector appears in no jvm*-server.options file on 5.0, 4.1 or 4.0, no Apache Cassandra ticket adds it to them, and project continuous integration does not exercise it. On those releases ZGC is an operator-supplied configuration rather than a supported option.
The project has stated its position. Its blog post on Java SE 11 support, published 24 February 2022 and covering 4.0.2 and later, records that ZGC is still experimental in Java 11, is not officially recommended, and is not fully supported until JDK 15. This documentation defers to that position and makes no recommendation of its own on ZGC. Where a lower-pause collector is the objective, the AxonOps recommendation is Shenandoah.
Cassandra 6.0, which has not reached general availability, adds conf/jvm21-server.options with generational ZGC active under JDK 21 (CASSANDRA-18831). That is the direction the project has taken rather than a configuration any cluster can run today, and it changes nothing on 5.0, 4.1 or 4.0.
What an Operator-Supplied Configuration Costs
Section titled “What an Operator-Supplied Configuration Costs”Among released Cassandra versions, 5.0 under JDK 17 is the only combination in which ZGC is a production feature of the JDK. Two consequences follow for a node run that way.
The collector combination has no upstream test coverage, so behaviour under Cassandra workloads is established by local testing alone. Nothing in the project’s continuous integration exercises the collector, and no release notes record behaviour under it.
GCInspector logs warnings against thresholds chosen for stop-the-world collectors, which produces noise under a concurrent collector (CASSANDRA-17751). Those warnings are not evidence of a problem under ZGC, and a node running the collector therefore loses the signal they carry under G1 and CMS.
# 5.0 under JDK 17 only, in jvm17-server.options-XX:+UseZGC
# Generational ZGC is JDK 21 and later. It must not be enabled under JDK 17:# the JVM does not recognise the option and the process does not start.# -XX:+ZGenerationalThe G1 lines in jvm17-server.options have to be commented out at the same time. -XX:+UseG1GC left active selects G1 whatever else the file contains, and the remaining G1 flags have no meaning to ZGC, so a file that keeps them describes a node that does not exist.
Flags That Do Not Transfer Between JDKs
Section titled “Flags That Do Not Transfer Between JDKs”-XX:+ZGenerational selects the generational mode of the collector and exists only from JDK 21. It must not be present in an options file read by a JDK 17 process: the JVM does not recognise the option and the process does not start.
-XX:SoftMaxHeapSize belongs only with ZGC, which uses it as a heap size to stay under when it can while leaving -Xmx as the hard limit. It was added for ZGC in JDK 13 (JDK-8222145). JDK 11, which 4.1, 4.0 and some 5.0 deployments run, does not have the option, and the JVM fails to start when an options file supplies it. G1 does not honour the flag in any released JDK (JDK-8236073), so it is not a setting that can be left in place while switching collectors. Shenandoah takes a differently named flag on JDK 11u; see Heap Sizing Under Shenandoah.
Verifying the Running Configuration
Section titled “Verifying the Running Configuration”The process arguments show which collector flag the JVM received:
ps -o args= -p "$(pgrep -fn CassandraDaemon)" | tr ' ' '\n' \ | grep -E 'UseZGC|UseG1GC|ZGenerational|SoftMaxHeapSize'A node intended to run ZGC that reports -XX:+UseG1GC has a G1 line still active earlier in the same file. nodetool gcstats then establishes the pause baseline for the node, which has to be measured rather than inferred, since the GCInspector warnings that flag long pauses under G1 and CMS carry no useful signal here for the reason given above.
Related Documentation
Section titled “Related Documentation”- JVM Tuning - Heap sizing, direct memory, GC logging and the procedure for applying a change
- G1 - Active on 5.0, and available on 4.1 and 4.0 as a commented block
- CMS - The collector 4.1 and 4.0 start with
- Shenandoah - The collector AxonOps recommends over G1, in no options file on any release
- JVM Architecture - The pointer-compression boundary, where the heap sits in process memory, and why the heap formula changed
- GC Pause Issues - Long pauses without an allocation failure