A Faster Path for Riemann's JVM Client Stack

The recent push on Riemann has centered on its client libraries and server-side parsing internals, with the JVM getting most of the attention. Boundary leans heavily on the JVM and on Coda Hale's Metrics library, so a new Riemann Java client was written to fit that ecosystem. The client supports UDP and TCP and comes with a Metrics reporter. That reporter can emit periodic events for every metric in a registry, optionally augmenting them with VM statistics. It supports prefixing each service and filtering with predicates; it has been tracking two production systems for roughly a week.

Riemann itself has now adopted this Java client, dropping the older Aleph-based one. The new implementation relies on standard Socket classes instead of Netty, so performance is roughly equivalent to the old client. Work from Mårten Gustafson and Edward Ribeiro was key to getting it production-ready.

Server-Side Netty Migration

On the server side, the last Aleph remnants have been removed. The TCP server is now a pure Netty implementation, and the Gloss library has been replaced with Netty's own length header parsers. That switch eliminates some data copying in the receive path.

The effect of these changes is visible in a single-threaded localhost benchmark where a client sends one event and waits for an OK response:

Aleph Raw Netty
drop tcp events latency.png drop tcp events latency 2.png
drop tcp events throughput.png drop tcp events throughput 2.png

Raw Netty throughput at steady state is roughly 2.5 times higher. Median and 95th-percentile latency both drop significantly, although occasional 20ms spikes remain, likely from garbage collection. These numbers should only be compared against each other; they depend heavily on the specific hardware and JVM setup. They also do not reflect concurrent load—the simplest case was optimized first before tackling higher concurrency. In practice, real-world performance with these changes should be "much faster".

Next Steps

The immediate roadmap includes replacing clojure-protobuf with direct use of the Java protobuf classes. Since data is already being copied into a standard Map, this should be slightly faster and will unify the codepaths between the server and client. Type-hinting of critical sections in the server and message parser is also planned to cut down on reflection overhead.