Liking cljdoc? Tell your friends :D

Soak & campaign results — index

On-cluster measurements of the soak arms (gRPC native-image, gRPC JVM, REST/Pedestal — identical 1-CPU/1-Gi Guaranteed pods on talos-main, one arm per worker; harness and procedure in ../soak/README.md). Each entry links the full results file and states its conclusion.

Executor grid — 2026-08-29

Conclusion: at low utilization the executor choice is a CPU/median-vs- tail trade — gRPC :executor :direct cuts CPU 35% and wins every p50 but roughly doubles p99 (event-loop convoying with deferred flushes), while Jetty's virtual-thread dispatch costs nothing on any axis and memory is invariant to threading everywhere. Zero failures in ~4.6M requests.

Unary capacity ramps — 2026-08-29/30

Conclusion: max sustainable goodput per identical 1-CPU pod — gRPC-JVM :direct ~2,140 req/s, VT ~2,060, native ~1,550, REST ~960 followed by queue-death (no admission control). At equal resources gRPC sustains 2.2× (JVM) / 1.6× (native) REST's throughput, and the executor trade inverts above ~75% utilization: :direct wins goodput and tails. A prototype grpc-netty drainNow() patch cut deep-saturation p99 64% (grpc-java#13012).

Streaming capacity — 2026-08-30

Conclusion: persistent bidi echo streams move ~15,000–16,000 msg/s on one core — ~7.5× the unary gRPC plateau and ~16× REST — with p50 <2 ms through 8,000 msg/s. The executors split only near saturation, where :direct holds p99 2–2.5× lower and keeps delivering at 16k: the per- message dispatch is the one cost streaming cannot amortize on the VT executor. The full doctrine across every measured regime: VT wins only low-utilization unary tails; :direct wins high-load unary, all streaming, capacity, and CPU — provided handlers never block.

Switch ladder — September 2026, in progress

Question: what does an existing REST service gain from each switch it could make — transport (HTTP/1.1 → h2c), protocol (REST/JSON → gRPC unary), interaction model (unary → stream) — with every adjacent pair of arms differing in exactly one thing, on one instrument (Nighthawk), at two payload sizes, with CPU attribution from the arms' own cgroup counters and Pyroscope. Conclusion: pending; phases land as the Nighthawk fork ships arm64, gRPC unary and per-message streaming.

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close