v3.2.2 is a stable patch release for production diagnostics, low-RSS evidence, and safer heavy
JSON tuning. The Java programming model is unchanged: handlers, services, components, records,
database code, and business logic stay in Java. Rust continues to own the HTTP I/O plane, bounded
native memory, file/static response paths, and selected low-allocation response paths.
- Maven dependency version is now
3.2.2. - Route diagnostics now separate production routes from benchmark-only comparison routes. The legacy DTO graph route remains measurable, but it no longer pollutes production heavy JSON counts.
- Heavy JSON diagnostics now correctly recognize direct primitive output writers such as
@DirectQueryIntplus(ByteBuffer out, int offset, int value). JsonBodyProducercan be returned directly for default200 OKJSON producer routes, avoiding the extraJsonProducerResponsewrapper allocation on hot paths.RawResponse handler(int value)is supported with direct scalar binding for cache/read-model routes that already have serialized bytes.- Optional route-local JNI admission is available for explicitly gated hot routes. It is not a global queue-size increase.
- Minimal production benchmark images now generate startup component and route indexes, so low-RSS measurements are not polluted by classpath-scan fallback behavior.
- Anonymous memory evidence is now first-class: benchmark tools report heap, JIT/code, class metadata, direct buffers, Rust-accounted memory, thread stack budget, and residual anon.
- Conservative idle native trim is validated as an opt-in memory reclaim policy for low-traffic, idle pods. It is still disabled by default.
<dependency>
<groupId>com.reactor</groupId>
<artifactId>rust-java-rest</artifactId>
<version>3.2.2</version>
</dependency>Use the normal Maven dependency in applications. Use rust-java-rest-3.2.2-core-runtime.jar only
when a benchmark or container classpath needs a single lean framework runtime jar. Do not use
rust-java-rest-3.2.2-sample.jar in production; it intentionally contains demo handlers, DTOs,
benchmark endpoints, and the bundled sample app.
| Use case | Use this first | Move to this when measured hot | Why |
|---|---|---|---|
| Normal small JSON | Java records | Direct primitive query/path binding | Keeps code simple; low overhead is already good |
| Hot DTO-shaped JSON | JsonBodyProducer / JsonProducerResponse |
Direct writer for very fixed shapes | Avoids building a large Java object graph |
| Already serialized JSON | RawResponse.json(bytes) |
RawResponse.registeredJson(...) for immutable/read-heavy data |
Skips DTO parse/serialize work |
| Immutable static JSON | @NativeStaticRoute |
Native registered response | Rust serves the response without Java handler work |
| File/export | FileResponse |
@NativeStaticFileRoute for immutable files |
Keeps file bytes out of Java heap |
| Legacy object graph comparison | @BenchmarkOnlyRoute |
Keep out of production gates | Useful for measurement, not as a target hot path |
BEST: keep normal business endpoints readable, then move only measured hot routes to producer, direct, raw, or native response paths. ANTI-PATTERN: globally increasing queues/workers to hide one heavy route's object graph or downstream bottleneck.
| Profile | Use when | Expected behavior |
|---|---|---|
micro-rest |
Small REST service, memory-first pod, controlled overload acceptable | Narrow queues, low RSS, bounded 503 under overload |
micro-rest-plus |
Same memory budget, but known heavy JSON routes need measured route budgets | Better c256/c512 heavy JSON behavior without global worker growth |
micro-dubbo |
REST service also uses the lightweight Dubbo consumer path | Keeps REST narrow and Dubbo surface explicit |
balanced / throughput |
You need smoother high-concurrency 200-only behavior | More headroom, more retained memory |
For low-traffic pods with long idle windows, enable native idle trim only after your own p99/503 gate:
reactor.rust.native-trim.enabled=true
reactor.rust.native-trim.initial-delay-ms=30000
reactor.rust.native-trim.interval-ms=60000
reactor.rust.native-trim.min-idle-ms=10000
reactor.rust.native-trim.max-active-connections=0
reactor.rust.native-trim.max-active-requests=0
reactor.rust.native-trim.retain-small=16
reactor.rust.native-trim.retain-medium=0
reactor.rust.native-trim.retain-large=0
reactor.rust.native-trim.retain-huge=0
reactor.rust.native-trim.allocator-trim-enabled=trueCurrent repeat-3 route gate, micro-rest-plus, cpu1, framework-only, c64/c256/c512/c1000:
| Diagnostic | Result |
|---|---|
| Production routes | 45 |
| Benchmark-only routes | 1 |
| Production heavy JSON object-graph routes | 0 |
| Benchmark heavy JSON object-graph routes | 1 |
This is the important production signal: the legacy DTO graph route is still available for comparison, but it is marked benchmark-only and excluded from production heavy-object-graph gates.
This is not a "zero reject at every concurrency" claim. It is a controlled-overload profile.
| Class | C | Avg RPS | Avg p99 | Reject % | Avg RSS after |
|---|---|---|---|---|---|
| raw-json | 64 | 8764 | 21.49 ms | 0.00% | 83.16 MiB |
| raw-json | 256 | 8345 | 70.63 ms | 0.00% | 82.93 MiB |
| raw-json | 512 | 7942 | 148.83 ms | 0.16% | 82.90 MiB |
| raw-json | 1000 | 4774 | 1270 ms | 2.82% | 82.21 MiB |
| dynamic-producer-json | 256 | 2319 | 227.06 ms | 0.77% | 82.35 MiB |
| dynamic-producer-json | 512 | 3198 | 291.03 ms | 22.74% | 83.43 MiB |
| direct-json-writer | 256 | 2293 | 219.08 ms | 0.50% | 82.95 MiB |
| direct-json-writer | 512 | 2798 | 376.16 ms | 16.57% | 84.04 MiB |
| dynamic-dto-json legacy | 512 | 3875 | 380.14 ms | 70.07% | 83.29 MiB |
Interpretation:
- Raw/precomputed JSON is the strongest low-overhead path.
- Producer/direct JSON is the right direction for hot DTO-shaped JSON, but c512/c1000 still need route budgets or a larger profile if the service must avoid 503.
- Legacy dynamic DTO graph remains supported, but it should not be the target path for hot heavy JSON.
Minimal production app, c64/c256/c512 anon evidence gate:
| Case | Current | Anon | Heap | JIT | Class metadata | Residual anon | Decision |
|---|---|---|---|---|---|---|---|
micro-rest |
66.71 MiB | 50.18 MiB | 4.16 | 2.50 | 10.59 | 29.34 | Baseline memory-first REST |
micro-rest-plus |
66.81 MiB | 50.47 MiB | 5.06 | 2.47 | 10.56 | 28.71 | Similar RSS; heavier route budgets |
micro-dubbo |
70.92 MiB | 50.48 MiB | 3.45 | 2.55 | 10.59 | 30.11 | Dubbo-enabled minimal surface adds current RSS |
| trim off | 64.51 MiB | 49.95 MiB | 5.27 | 2.46 | 10.59 | 25.98 | No idle reclaim |
| trim on conservative | 46.97 MiB | 31.87 MiB | 3.29 | 2.46 | 10.63 | 12.02 | Best proven idle reclaim |
Key result: conservative idle trim reclaimed about 18 MiB cgroup anon and 17.5 MiB cgroup
current after idle. That is useful for low-traffic pods. It is not a default throughput setting.
mvn -q testmvn -q -DskipTests package- Route diagnostics benchmark: c64/c256/c512/c1000, repeat
3,micro-rest-plus, framework-only. - Minimal anon evidence gate:
micro-rest,micro-rest-plus,micro-dubbo, trim off/on A/B, c64/c256/c512. - Jar policy: normal jar and
core-runtimeexclude framework sample/benchmark classes; sample jar intentionally keeps them.
Release assets include:
rust-java-rest-3.2.2.jarrust-java-rest-3.2.2-core-runtime.jarrust-java-rest-3.2.2-sample.jarrust-java-rest-3.2.2-sources.jarrust-java-rest-3.2.2-javadoc.jarrust_hyper-windows-x64.dlllibrust_hyper-linux-x64.soSHA256SUMS