Skip to content

Configuration Reference

Default is usually right

For 95% of production deployments, use default (the agent default) with LZ4FRAMED compression (also the default). You do not need to change this. The rest of this page exists for the 5% who need tighter compression or full nanosecond fidelity.

Two independent axes

cjfr has two orthogonal knobs, and it helps to keep them separate:

  1. Condenser config (--condenser-config) — what data is reduced. This is a one-way, lossy transform applied while reading JFR events: dropping precision, combining events, trimming stacks. Reduced data cannot be recovered on inflation.
  2. Compression (--compression, --compression-level) — how the resulting byte stream is packed. This is fully lossless and reversible; it only affects file size and CPU, never the data that comes back out.

You can mix any config with any compression. The condenser config is the bigger size lever; compression on top is incremental.

Condenser Configurations

The --condenser-config flag controls how aggressively JFR events are reduced. All configurations produce valid .cjfr files. Loss is one-way: data reduced during condensing cannot be recovered on inflation.

For GC profiling, default is the right choice for almost all production deployments; it preserves all GC pause durations, heap sizes, promotion data, and allocation rates at millisecond precision, which is far more than enough for GC tuning and capacity planning.

lossless

Full fidelity. Only structurally redundant data is removed (no-op events like GC region changes where nothing changed). Everything else is preserved verbatim.

Sizes (with LZ4FRAMED, the default compression): ~8–42% of the original JFR. Lower for gc_details-heavy recordings (~17% on G1 renaissance); higher for sparse gc-only profiles (~41%).

Use when: - You need exact nanosecond timestamps - You need source-file line numbers and bytecode index (BCI) in stack frames - You need per-allocation object sizes in TLAB/PLAB events - You need stacks deeper than 32 frames - You are doing forensic analysis or benchmarking

Preserved: nanosecond timestamps, microsecond durations, full stack traces (unlimited depth), exact memory sizes (lossless integer), all allocation events, all exception events.

Removed: provably empty events (e.g. G1HeapRegionTypeChange events with no change).


default

Conservative lossy compression. Human-readable precision is fully preserved. Loses sub-millisecond timestamp precision, BCI/line numbers in stacks, and very short or zero-valued GC data.

Sizes (with LZ4FRAMED, the default compression): ~4–17% of the original JFR. Lower for gc_details-heavy recordings (~7% on G1 renaissance); higher for sparse gc-only profiles (~17%).

Use when: - Production long-term storage and capacity planning - GC tuning (pause durations, heap sizes, promotion data are all accurate) - You want a ~2× size saving over lossless with minimal analytical impact

Defaults to: the Java agent (-javaagent:cjfr.jar=start,...)

Changes from lossless:

Field lossless default
Timestamp resolution nanosecond millisecond
Duration resolution nanosecond microsecond
Memory sizes lossless integer bfloat16 (~0.4% relative error, e.g. ±4 MB on a 1 GB heap)
Stack depth limit unlimited 32 frames
BCI / source line in stacks yes no
Zero-count tenured ages included dropped
Sub-threshold GC pauses included dropped
PLAB promotion events per-event combined
Unnecessary addresses included dropped

bfloat16: 16-bit brain floating-point format used for heap size fields. PLAB: Promotion Local Allocation Buffer; per-thread buffer used during young-to-old promotion in G1GC. BCI: bytecode index (position within a method's bytecode, used for precise source-line mapping).


reduced

Aggressive lossy compression. Suitable for bulk archival and fleet-wide recordings where storage cost outweighs per-event granularity.

Sizes (with LZ4FRAMED, the default compression): ~1–11% of the original JFR. Lower for gc_details-heavy recordings (~4% on G1, ~1.4% on ZGC renaissance); higher for sparse gc-only profiles (~11%).

Use when: - Fleet-wide continuous recording where storage is expensive - You only need aggregate metrics (total GC time, pause percentiles, heap trend) - You can tolerate losing per-allocation object sizes and per-exception events

Changes from default:

Field default reduced
Stack depth limit 32 frames 16 frames
Type info in stack frames yes no
ObjectAllocationSample events per-event combined into buckets
TLAB/PLAB allocation sizes per-event summed
Exception events per-event combined (same exception class)
G1 heap region changes per-event combined
MonitorEnter / ThreadPark per-event combined

TLAB: Thread-Local Allocation Buffer; fast-path per-thread allocation region; TLAB/PLAB events record individual object allocation sizes. Combined means only the total bytes allocated per rotation interval is preserved.


Config Summary Table

Feature lossless default reduced
Size (% of JFR, with LZ4FRAMED) 8–42% 4–17% 1–11%
Nanosecond timestamps ✗ (ms) ✗ (ms)
Source line / BCI in stacks
Stack depth unlimited 32 16
Per-allocation object size ✗ (summed)
Per-exception events ✗ (combined)
GC pause durations
Heap sizes ✓ (bfloat16) ✓ (bfloat16)
Safe for cjfr inflate ✓* ✓*

*Inflated output reflects the reduced precision (e.g. ms-resolution timestamps, no BCI). Inflation does not restore lost data; it only converts the format.


Raw flag table

The boolean reduction flags behind each preset, generated from the code (Configuration.toFlagTable()) and verified in ConfigurationDocTest. Do not edit this table manually — it is regenerated automatically by the test suite:

flag lossless default reduced
memoryAsBFloat16 no yes yes
ignoreUnnecessaryEvents yes yes yes
useSpecificHashesAndRefs yes yes yes
combineEventsWithoutDataLoss yes yes yes
combinePLABPromotionEvents yes yes yes
combineObjectAllocationSampleEvents no no yes
sumObjectSizes no no yes
ignoreZeroSizedTenuredAges no yes yes
ignoreTooShortGCPauses no yes yes
removeBCIAndLineNumberFromStackFrames no yes yes
removeTypeInformationFromStackFrames no no yes
removeUnnecessaryAddresses no yes yes
combineExceptionEvents no no yes
combineG1HeapRegionTypeChangeEvents yes yes yes
combineBlockingEvents no no yes
combineThreadParkLossless yes yes yes
dropGCWorkerThreadFromGCPhaseParallel no no yes

Compression Algorithms

The --compression flag selects the inner byte-stream compression. This is independent of event reduction above.

cjfr condense --compression=<value> recording.jfr

Accepted values: NONE, GZIP, LZ4FRAMED.

Note

The .cjfr format reserves space for additional algorithms, but only NONE, GZIP, and LZ4FRAMED are implemented. Passing any other value is rejected by the CLI.

Value Speed (write) Speed (read) Ratio Use case
LZ4FRAMED (default) Very fast Very fast Good Agent recording, streaming, frequent reads
GZIP Slow Moderate Good Long-term archive; compatible with standard gzip tooling
NONE Instant Instant None Benchmarking the condenser itself; transport with built-in compression

LZ4FRAMED uses block-independent framing: each block can be decompressed independently. This makes recordings resilient to partial file corruption and allows streaming reads without buffering the entire file.

Compression level

--compression-level selects how hard the compressor works: FAST, MEDIUM, HIGH_COMPRESSION (default), MAX_COMPRESSION. Higher levels trade write CPU for a smaller file; they do not change the data or the read path. The chosen level is recorded in the file's start header, so tools can report it.

Archiving: reduced + MAX_COMPRESSION

For cold, long-term archives where write time is irrelevant and every byte counts, combine the reduced config with MAX_COMPRESSION:

cjfr condense --condenser-config reduced --compression-level MAX_COMPRESSION recording.jfr archive.cjfr

Combining config and compression

Compression and condenser config are independent knobs. The biggest size reduction comes from choosing the condenser config; compression on top is incremental.

Config + Algorithm Approx. % of original JFR
lossless + LZ4FRAMED 8–42%
lossless + GZIP 7–35%
default + LZ4FRAMED 4–17%
default + GZIP 3–15%
reduced + LZ4FRAMED 1–11%
reduced + GZIP 1–10%

Lower bound = gc_details-heavy workloads (many events); upper bound = sparse gc-only profiles. Measured on renaissance benchmarks.

For most production deployments: default + LZ4FRAMED (the agent default) is the right choice; fast writes, fast reads, 4–17% of original size depending on workload type.