Live data from Hacker News

Don't Use Protobuf for Telemetry

richardstartin.github.io

21–30 of 195 posts

Re: Don't Use Protobuf for Telemetry

#21

Is this a thing people care about? From what I've seen of server-side Java applications (we have several at work) 1.6MB and 700 classes are lost in the noise of the endless list of Maven dependencies. I'm sure you can do it a lot more efficiently without using someone else's thing, but what exactly is being optimised for here?

That was kinda my response as well. If telemetry altogether is using more than 1% of your cpu time you have an architectural problem perhaps.

Re: Don't Use Protobuf for Telemetry

#22
post #14

Google's own protobuf runtime is so bloated that even google themselves don't use it in many of their software, but rather nanopb[1], which is done by completely unrelated person to google. 1: https://jpa.kapsi.fi/nanopb/

I don’t think that’s true in google3. People often mistake the scale of Google’s internal code with respect to their visible external code.

Re: Don't Use Protobuf for Telemetry

#23
post #14

Google's own protobuf runtime is so bloated that even google themselves don't use it in many of their software, but rather nanopb[1], which is done by completely unrelated person to google. 1: https://jpa.kapsi.fi/nanopb/

I am only aware of nanopb being used at Google in embedded scenarios. The primary reason for the project I worked on was that the first Pixel Buds didn't have a C++ compiler (at least not a functional one - based on GCC 2 or 3 if I recall correctly & an extremely crippled implementation). Pixel Buds 2 didn't have that limitation (stock GCC 9) but nanopb was kept for the second Pixel Buds because the memory management was saner for an embedded RTOS environment (vs stock upstream that might use STL or otherwise try to allocate memory). I don't think runtime bloat was really on our radar (it could have been the next critical path, but wasn't on our radar at the time).

Nanopb itself needed some changes to the codegen for the first Pixel Buds (which I investigated & fixed) due to architectural peculiarities of the CSR8675. It generated a lot of constants but the CSR8675 had limited space there & was made worse because every 8 bits took up 1 16-bit word (e.g. the size of your string literal or any constant byte array is effectively doubled). So I changed the code gen to put those constants in the code section instead. Before this change resolved the issue more fully, random engineers who were unlucky enough to add a constant in some way were hitting limits internally with regularity (as the project was heading toward ship) & working around it by removing characters from log messages (e.g. "Some long message" => "Sme lng msg").

For what it's worth I tried to contribute any meaningful improvements we made back to nanopb but this one didn't make that cut as it was specific to a chip no one in the wider community would be using anyway (8675 is super old).

I don't exclude the possibility of it using in more places, but I'd say the average Google engineer does not encounter nanopb in their daily development.

Re: Don't Use Protobuf for Telemetry

#24
post #14

Google's own protobuf runtime is so bloated that even google themselves don't use it in many of their software, but rather nanopb[1], which is done by completely unrelated person to google. 1: https://jpa.kapsi.fi/nanopb/

> even google themselves don't use it in many of their software

Citation needed. Granted its a big company, so its certainly possible that some teams I'm unaware of were using it. But I never ran into one.

Besides, nanopb doesn't answer the critique of the article. Nanopb cuts down on heap traffic by statically allocating flat buffers large enough to hold maximums set by the application. It solves the two-pass problem by the simple expediency of actually running two passes, storing the size info on the ordinary call stack. In effect, it trades malloc/free traffic for higher peak memory utilization.

At the largest scales, big G suffers from total memory pressure more than it suffers from lack of arithmetic. Nanopb isn't a good trade for them. It is a good trade for my current (hard realtime, embedded) application.

Re: Don't Use Protobuf for Telemetry

#25
post #4

His point on protobuf-java library adding nontrivial bloat to his Java app is definitely valid. However, his other argument about protobuf wire format being inefficient is hard to square with decades of practical experience Google had with protobufs, which are used for literally everything, including telemetry, and high throughput, low latency applications. Sure, having to recursively precompute lengths before serial…

It seems easy to square the practical experience of protobufs at Google versus the tradeoffs encountered in the wire format when you take into account how many Google engineers have directly contributed to the diaspora of related formats such as CapnProto, flatbuffers, msgpack, etc with different tradeoffs (especially for smaller scales than Google).

It seems clear enough that protobufs were optimized in a scale that involved a lot of time/cost-sensitive reads and far fewer time/cost-sensitive writes. That's a valid tradeoff for Google scale, that comes at a cost of other potential applications (such as telemetry that can be very time/cost-sensitive at write-time but has much more relaxed read time/cost-sensitivity).

> Sure, having to recursively precompute lengths before serialization is a bit of a hassle, but I wouldn’t call it expensive.

It's expensive in memory (needing to prebuild all the subcomponents of the message, instead of streaming them as needed), and potentially time (prebuilding then sending, versus streaming as soon as data is available to write). Of course, in the scheme of things it may not be expensive to particular use cases. (Which seems why the author seems to particularly highlight this specific use case where such things really are expensive overhead necessary to avoid.)

Re: Don't Use Protobuf for Telemetry

#26

Earlier quoted context omitted.

Signal boosting this. I am the last person to be swayed by “use our magical design that solves all problems,” but in the case of protobufs, it solves most of them. I didn’t like it until I was forced to use it. Now I’m not sure I’ll ever go back. There’s a handy code snippet to turn any protobuf message into JSON: from google.protobuf.json_format import MessageToJson import json from pprint import pprint as pp pp(jso…

Why they use Java like code in Python? "MessageToJson" doesn't look idiomatic.

CapWords function names matches the C++ style guide at Google, not java. A lot of python uses autogenerated bindings to C++ code and reuses the same naming conventions. Even pure python code would use that style although their public styleguide doesn't mention it anymore.

Re: Don't Use Protobuf for Telemetry

#27
Protobuf's variable-length lengths are indeed annoying, but can't you encode back-to-front as in ASN.1? That lets you write your lengths just after encoding the value, which should work (but may leave your data in e.g. bytes 20+ of a buffer; depending on interfaces, you may need to do one final copy to move the data to the start of the buffer.)

(ASN.1 and protobuf are both tag-length-value formats with variable-length integer encodings... h/t to tptacek for mentioning that particular trick.)

Re: Don't Use Protobuf for Telemetry

#28
Ay my previous job we started out using simple StatsD messages that are a few bytes long, easy to implement, easy to debug, and quick.

But then possibly due to a full-steam-ahead mandate of "everything should use protobuf (or was it thrift)?", we switched to a much heavier format, where clients needed a codegen'd binary implementation of the protocol, while making messages themselves much heavier.

Re: Don't Use Protobuf for Telemetry

#29
post #21

Is this a thing people care about? From what I've seen of server-side Java applications (we have several at work) 1.6MB and 700 classes are lost in the noise of the endless list of Maven dependencies. I'm sure you can do it a lot more efficiently without using someone else's thing, but what exactly is being optimised for here?

That was kinda my response as well. If telemetry altogether is using more than 1% of your cpu time you have an architectural problem perhaps.

My experience points to the cost of storing metrics far outweighing the cost of emitting metrics in all but the most extreme of circumstances.
Post reply on HN