You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Protobuf has zero-copy support to avoid copying string/bytes fields when parsing protobuf messages and it's used pretty much everywhere inside Google, but the feature has never made its way into the opensource repo. Now protobuf 3.0.0 is released and we will probably have more time to look into incremental improvements. The zero-copy API is a good candidate to be included in the next 3.x release.
Opensourcing the zero-copy API will involve:
opensource related string/buffer classes (Cord and its dependencies).
un-exclude zero-copy APIs from the message interface (such as ParseFromStringWithAliasing).
un-exclude the support for ctype = STRING_PIECE and ctype = CORD.
(1) is probably the most difficult part as that's a large chunk of code and it may not be portable.
@jjyao This unfortunately hasn't made into our agenda yet. If this feature is useful to you, can you post here your use case and estimate how much it can help? More concrete use case example can help us prioritize it.
More concrete use case example can help us prioritize it.
@xfxyjwf I'm writing an application-specific database server with gRPC and RocksDB. I want to:
Accept serialized protos from clients through gRPC and store them in RocksDB verbatim, without parsing and constructing a full object in memory.
Retrieve serialized protos from RocksDB and send them back to clients without parsing and reserializing them, ideally as part of another proto, which would serialize only what's necessary.
I want this because parsing and serialization currently take ~30% of my total response time and I don't really need them.
Reacted by Stellan Haglund, Eli Bar-Yosef, Stefan Hagen, Markus Padourek, Wesley Kerfoot, High Sense, Stéphane Lavergne, Aman Deep Gautam, WANG YEFU and Suraj
@stellanhaglund No, it's not the main cause of the performance difference. cap'n proto is very similar to FlatBuffer and what I described in #3296 can be said to cap'n proto as well.
I am very interested in this feature. I have been suggesting at my work that we adopt something like protobuf for a long time. One of the major push backs has been the ability to zero copy large binary/string values. This is because we have many applications where an extra copy or two of the data means the processors/memory bus is now saturated.
Our usual process stream for data look a lot like:
DMA from network interface to shared memory
pass off the shared memory reference to the process(es) to do calculations
calculations done from shared memory to shared memory
pass shared memory reference to further process(es)
DMA out of the machine
Control message and meta data are small enough that copying is no problem (and in fact encoding as json etc. is usually good enough). Typical data is large matrices (think 16+MB) of complex integer (often 16 bit), complex IEEE binary16 (half) or complex IEEE binary32 (float). While meta data may be 64 bytes in total encoded as a struct. Note we often also have the requirement that the data be machine vector aligned (typically 32 byte align). A "slow" data rate is 3-5 Gigabit/s.
It'd be great if we could encode such data as something like protobuf and not have to manually maintain readers and writers and representations in multiple languages. We are already making an effort to use protobuf for control data, which IMO it already excels at.
Reacted by chris-hite, Stefan Hagen, KeertiNarayan, Mayank Shekhar Narula, Markus Padourek, Stéphane Lavergne, Aman Deep Gautam, GITWHB and Suraj
@arthur-tacca Yep. The Cord type will be included as part of Abseil. And after we migrate to use Abseil, supporting zero-copy ctypes should be straightforward.
Hello, I ran into some performance problems at my previous HFT job an thought it be nice to have a zero-copy, heap free, protobuf parser.
If I were going to hand write code that parsed a specific protobuf schema, I'd typically do all my processing on the stack and consume all data in one pass.
I could see writing a C++ functional template heavy low level decoder giving me the same performance. I would best describe it as X(name proposals welcome) is to SAX as regular protobuf bindings are to DOM.
instead of heaping a std::string, you get a std::string_view.
if you don't care about a field you should be able to say so at compile time
if you don't want to parse a subobject you should be able to skip it or even break out of parsing
On the generation side I could see doing something something similar.
it should be possible for a message routing app to pass payloads without decoding them
Is there interest for this kind of thing? My fear is that C++ guys that really care about performance would avoid protobuf anyway. I guess my target audience are skilled C++ devs worried about performance forced to speak protobuf for historical reasons or a contract with outside components.
Does anyone have a spiffy name?
Has anyone seen something like this? I found lots of alternative wire formats with language bindings: SBE, CapNProto, etc.
I don't think we would switch to using a SAX-like parser except maybe in some very specific circumstances in our project. For us, the overhead of most PBs is negligible (and I expect to be even lower when we switch to using arenas). The main exception is the std::string allocation of lots of tiny strings -- we're stuck on the pre-C++11 ABI, so every string ends up being a heap allocation/free pair.
We triage inactive PRs and issues in order to make it easier to find active work. If this issue should remain active or becomes active again, please add a comment.
This issue is labeled inactive because the last activity was over 90 days ago. This issue will be closed and archived after 14 additional days without activity.
2026 update: C++Proto does have some support for aliasing, but only if you parse out of a Cord and only Cord-typed fields can be aliased.
Note that this design has no guarantee that it won't copy some things: it needs to be treated as a pure optimization only, it cannot be used to keep your data a controlled section of memory, you can't do it to guarantee the parsed data never reaches the heap, etc.
There's an additional part of this that has been held back for now while some other (slowly landing) shifts towards string_view have been happening. The issue is that if accessors hand out const std::string& it needs to be pointing at a real std::string, they cannot alias the original buffer without some sketchy workarounds. So unfortunately our standard gencode API shape has effectively been incompatible with aliased parsing, and while we're shifting to string_view accessors that shift hasn't gone far enough yet to be able to support aliased parsing, so it is still only available for Cord inputs and Cord fields.
But note that even after we get the string_view accessors stuff into good enough shape, its just not the case that C++Proto is designed to keep data in the trusted memory. It is a known but somewhat fringe usecase that has been discussed internally and externally, and its unfortunately just not realistic for us to provide that guarantee with the other priorities that the library has; other solutions will unfortunately need to be found for usecases that require that level of control over memory.
So as of June 2026 issue is some combination of:
Fixed (Cord/Cord aliasing)
Still pending with no ETA we can announce today (string_view aliasing)
Wontfix (promises that the library won't copy data out of the parsed buffer)
Activity
jjyao commentedon Feb 15, 2017
Any updates on this feature?
xfxyjwf commentedon Feb 15, 2017
@jjyao This unfortunately hasn't made into our agenda yet. If this feature is useful to you, can you post here your use case and estimate how much it can help? More concrete use case example can help us prioritize it.
bobobo1618 commentedon Jun 24, 2017
I'm also quite interested in this feature.
@xfxyjwf I'm writing an application-specific database server with gRPC and RocksDB. I want to:
I want this because parsing and serialization currently take ~30% of my total response time and I don't really need them.
Here's a flame graph profile that shows what I'm seeing.
stellanhaglund commentedon Jul 2, 2017
Is this the thing that cap'n proto does that makes it fast than protobuf?
xfxyjwf commentedon Jul 5, 2017
@stellanhaglund No, it's not the main cause of the performance difference. cap'n proto is very similar to FlatBuffer and what I described in #3296 can be said to cap'n proto as well.
johnfb commentedon Sep 26, 2017
I am very interested in this feature. I have been suggesting at my work that we adopt something like protobuf for a long time. One of the major push backs has been the ability to zero copy large binary/string values. This is because we have many applications where an extra copy or two of the data means the processors/memory bus is now saturated.
Our usual process stream for data look a lot like:
Control message and meta data are small enough that copying is no problem (and in fact encoding as json etc. is usually good enough). Typical data is large matrices (think 16+MB) of complex integer (often 16 bit), complex IEEE binary16 (half) or complex IEEE binary32 (float). While meta data may be 64 bytes in total encoded as a struct. Note we often also have the requirement that the data be machine vector aligned (typically 32 byte align). A "slow" data rate is 3-5 Gigabit/s.
It'd be great if we could encode such data as something like protobuf and not have to manually maintain readers and writers and representations in multiple languages. We are already making an effort to use protobuf for control data, which IMO it already excels at.
arthur-tacca commentedon Sep 28, 2017
Perhaps Cord will / could be open sourced as part of the Abseil library. The initial release doesn't include it, although there is a passing mention in
malloc_extension.h.xfxyjwf commentedon Sep 28, 2017
@arthur-tacca Yep. The Cord type will be included as part of Abseil. And after we migrate to use Abseil, supporting zero-copy ctypes should be straightforward.
chris-hite commentedon Apr 24, 2018
Hello, I ran into some performance problems at my previous HFT job an thought it be nice to have a zero-copy, heap free, protobuf parser.
If I were going to hand write code that parsed a specific protobuf schema, I'd typically do all my processing on the stack and consume all data in one pass.
I could see writing a C++ functional template heavy low level decoder giving me the same performance. I would best describe it as X(name proposals welcome) is to SAX as regular protobuf bindings are to DOM.
On the generation side I could see doing something something similar.
Is there interest for this kind of thing? My fear is that C++ guys that really care about performance would avoid protobuf anyway. I guess my target audience are skilled C++ devs worried about performance forced to speak protobuf for historical reasons or a contract with outside components.
Does anyone have a spiffy name?
Has anyone seen something like this? I found lots of alternative wire formats with language bindings: SBE, CapNProto, etc.
toddlipcon commentedon Apr 24, 2018
I don't think we would switch to using a SAX-like parser except maybe in some very specific circumstances in our project. For us, the overhead of most PBs is negligible (and I expect to be even lower when we switch to using arenas). The main exception is the std::string allocation of lots of tiny strings -- we're stuck on the pre-C++11 ABI, so every string ends up being a heap allocation/free pair.
61 remaining items
tech-sedge commentedon Dec 26, 2025
Bump
github-actions commentedon Mar 27, 2026
We triage inactive PRs and issues in order to make it easier to find active work. If this issue should remain active or becomes active again, please add a comment.
This issue is labeled
inactivebecause the last activity was over 90 days ago. This issue will be closed and archived after 14 additional days without activity.AustinSchuh commentedon Apr 1, 2026
Pretty sure this is still relevant.
esrauchg commentedon Jun 22, 2026
2026 update: C++Proto does have some support for aliasing, but only if you parse out of a Cord and only Cord-typed fields can be aliased.
Note that this design has no guarantee that it won't copy some things: it needs to be treated as a pure optimization only, it cannot be used to keep your data a controlled section of memory, you can't do it to guarantee the parsed data never reaches the heap, etc.
There's an additional part of this that has been held back for now while some other (slowly landing) shifts towards string_view have been happening. The issue is that if accessors hand out
const std::string&it needs to be pointing at a realstd::string, they cannot alias the original buffer without some sketchy workarounds. So unfortunately our standard gencode API shape has effectively been incompatible with aliased parsing, and while we're shifting to string_view accessors that shift hasn't gone far enough yet to be able to support aliased parsing, so it is still only available for Cord inputs and Cord fields.But note that even after we get the string_view accessors stuff into good enough shape, its just not the case that C++Proto is designed to keep data in the trusted memory. It is a known but somewhat fringe usecase that has been discussed internally and externally, and its unfortunately just not realistic for us to provide that guarantee with the other priorities that the library has; other solutions will unfortunately need to be found for usecases that require that level of control over memory.
So as of June 2026 issue is some combination of:
danieljennings commentedon Sep 21, 2026
Bump