Welcome!

Here I mostly write about software engineering problems I’ve encountered.

Diagnosing memory leaks in Java applications

Despite being a garbage-collected language, memory leaks are still possible (and quite common) in Java. The simplest example is an in-memory data structure that grows with every unit of work performed by the system. For example, imagine you store an in-memory log for every request/response you process, and never bound the size or flush to disk. Some other examples include: File leaks, where a file or socket is not closed. These consume both memory and OS file handles and will eventually fail....

July 1, 2023 · 5 min · Gautam Raj

Java performance profiling

For me, one of the most fun parts of software development is making software run as fast as possible. Performance tuning has very simple objective metrics - maximize throughput, minimize latency and compute cost. It can sometimes require detective work and intuition to understand where a bottleneck might be coming from. Fortunately, there is some excellent tooling for the JVM which I’ll talk about here. Performance is a very broad topic, so for this post I’ll focus on CPU bottlenecks....

May 4, 2023 · 3 min · Gautam Raj

Reflections on building a Java service framework (part 1)

Background I spent several years at Stripe building a Java services framework, as a replacement for the existing aging Ruby monolith. There aren’t a lot of resources around building a framework, so I thought I’d share some details about the framework, and some of the lessons we learned along the way. The framework I describe here wasn’t built by only me, but was a collaborative effort from across the company, and with a lot of helpful input from our internal developers....

April 19, 2023 · 7 min · Gautam Raj

Robust iterators for gRPC server-side streams in Java

One useful feature of gRPC is server-side streaming. A client can use this to stream over large amounts of data from a server, for example the result of a large database query. The “blocking” API for this has a familiar Iterator API: Iterator<StreamResponse> iterator = blockingStub.makeStreamingCall(); while (iterator.hasNext()) { StreamResponse response = iterator.next(); // do stuff } However, there are a few hidden issues to think about here: What happens if we get a network error halfway through the stream?...

April 18, 2023 · 4 min · Gautam Raj