In our case we've now over 1T of rows. Storing default variables would be incredibly inefficient and expensive.
Is nullability of primitive types what you're missing? As in, having a boolean value that can be true, false, or null. If you need that, defining your field as google.protobuf.BoolValue instead of bool gives you that (same with the other primitive types: https://github.com/google/protobuf/blob/master/src/google/pr... ). But making primitive types never null aligns proto3 with most programming languages, making the generated code more idiomatic and performant.
Does capnproto provide similar RTTI information to walk through properties or recurse into other messages?
It's actually considerably easier to implement for Cap'n Proto since the in-memory objects are actually backed by byte buffers containing the wire format. No need to compute offsets of class members (which technically violates the C++ standard though it works on all compilers).
Does this mean that individual fields are encoded/decoded lazily?
(But every widely-used arch these days is LE.)
2) protobuf in the proto3 design doesn't cary default values. So if you have a bool field and want to explicitly send false, well you have to change it to some other type or use the default values all the time
3) protobuf generates incredibly large serialization/deserialization support coce for each template. For some languages like Python in can be in hundreds of kilobytes. Cap'n proto messages are significantly smaller
There is more for CnP but Protobuf has much better support and is by default used in projects like gRPC. Also new CnP is lacking speed in new development in comparison to Protobuf.
But I'm using in one of my side projects and I'm very happy with it