You'll notice there is a lot of copying that is happening, which has a potential for being streamlined. In theory the passing-by-reference with the functional programming approach of updating the data is a natural direction, but currently different components of the program have specific object types they understand and expect for processing.
There are some nice discussions happening around multi-buffer allocation, consolidated buffers before a write, zero-copy for the data portion with WriteCombiningHandler performing the serialization:
This is a fun problem, which I imagine others might encounter when using gRPC-Java. So let's explore ways to optimize this for large payloads, and discuss tweaks to gRPC-Java to make this possible.