Live data from Hacker News

Zero-copy protobuf and ConnectRPC for Rust

medium.com

31–40 of 47 posts

Re: Zero-copy protobuf and ConnectRPC for Rust

#31
post #21

I previously worked at Bytedance and we've maintained a Rust zero-copy gRPC/Thrift implementation for 4 years: https://github.com/cloudwego/volo , it is based on Bytes crate (reference counting bytes, for folks don't familiar with Rust ecosystem). A fun fact: when we measuring on our product environment, zero-copy isn't means higher performance in lots of scenarios, there are some trade-offs: 1. zero-copy means bytes…

same thing with io_uring zero copy in my limited testing: buffer usage accounting is not free and copying memory makes things drastically simpler.

Re: Zero-copy protobuf and ConnectRPC for Rust

#32
This is very cool! I’m most interested in the protobuf runtime - Rust has historically used Prost, which doesn’t pass the protobuf compliance test suite and isn’t Google-maintained. Google’s priority internally is cpp interop, so they use unsafe for protobuf - which the community is understandably not excited about.

(For full disclosure, I started the ConnectRPC project - so of course I’m excited about that part of the announcement too.)

Re: Zero-copy protobuf and ConnectRPC for Rust

#33

Earlier quoted context omitted.

Is this still true? New versions of protobuf allow codegen of `std::string_view` rather than `const std::string&` (which forces a copy) of `string` and `repeated byte` fields. https://protobuf.dev/reference/cpp/string-view/

It allows avoiding allocations, but it doesn't allow using serialised data as a backing memory for an in-language type. Protobuf varints have to be decoded and written out somewhere. They cannot be lazily decoded efficiently either: order of fields in the serialised message is unspecified, hence it either need to iterate message over and over finding one on demand or build a map of offsets, which negates any wins zer…

This is true but the relative overhead of this is highly dependent on the protobuf structure in one's schema. For example, fixed integer fields don't need to be decoded (including repeated fixed ints), and the main idea of the "zero copy" here is avoiding copying string and bytes fields. If your protobufs are mostly varints then yes they all have to be decoded, if your protobufs contain a lot of string/bytes data then most of the decoded overhead could be memory copies for this data rather than varint decoding.

In some message schemas even though this isn't truly zero copy it may be close to it in terms of actual overhead and CPU time, in other schemas it doesn't help at all.

Re: Zero-copy protobuf and ConnectRPC for Rust

#35
I wanted to recall what protobuf is, but when I opened the docs I didn't see the binary structure - the most important part - instead there are some code examples which are less important. If you are making a serialization format, please begin the docs with wire format diagrams.

Re: Zero-copy protobuf and ConnectRPC for Rust

#36
post #34

I'd like to use this, but I don't want to refactor all my services when they change the request/response types. Interested to know the timing of 1.x. It seems to be moving pretty fast atm - hopefully that momentum keeps going.

As I understand, protobuf has compatibility (it stores field ids), so new service can read request from older client, and vice versa, so you do not need to refactor anything. Also, it is made for long-range communications, and is inefficient for inter-process or inter-thread messaging.

Re: Zero-copy protobuf and ConnectRPC for Rust

#37

It's 2026 and I'm still defining my own messaging and wire protocols. Plain C structs that fit in a UDP datagram that you can reinterpret_cast from is still best. You can still provide schemas and UUIDs for that, and dynamically transcode to JSON or whatever.

What you use is perfect for short-range communication (application and child process talking over shared memory), but not good for long-range communication (over Internet) because you can have old client talking to new version of a server, so you will have to add version numbers and have the code to parse outdated formats. But protobuf has compatibility built in and you do not need to write anything to support outdated clients. Also, protobuf uses solutions like varints to compress data to use less network traffic. So it is obviously made for long-range communication, and you probably do not have that and send 7 zeros for every small number.

TL;DR protobuf has version compatibility and compact number encoding.

Re: Zero-copy protobuf and ConnectRPC for Rust

#38
post #30

It's 2026 and I'm still defining my own messaging and wire protocols. Plain C structs that fit in a UDP datagram that you can reinterpret_cast from is still best. You can still provide schemas and UUIDs for that, and dynamically transcode to JSON or whatever.

Until you have to work with big and little endian systems. There are other weirdness about how different computers represent things as well. utf-8 / ucs-16 strings (or other code pages). Not all floats are ieee-754. Still when you can ignore all those issues what you did is really easy and often works.

I disagree. Big endian is long dead and not worth worrying about. And code pages too. What is more important, is dealing with schema changes, when you add new fields to requests and responses.

Re: Zero-copy protobuf and ConnectRPC for Rust

#39
post #28

It's 2026 and I'm still defining my own messaging and wire protocols. Plain C structs that fit in a UDP datagram that you can reinterpret_cast from is still best. You can still provide schemas and UUIDs for that, and dynamically transcode to JSON or whatever.

Provided that: - you agree never to care about endianness (can probably get away with this now) - you don't want to represent anything complicated or variable length, including strings

You can have strings by using relative pointers ("string starts 123 bytes before this").
Post reply on HN