5 ms·
Yes, all of it. Google claims gRPC with protobuf yields a 10-11x performance improvement over HTTP. I am skeptical of those numbers because really it comes do
by austin-cheney 2y ago
Yes, all of it.
Google claims gRPC with protobuf yields a 10-11x performance improvement over HTTP. I am skeptical of those numbers because really it comes down to the frequency of data parsing into and out of the protobuf format.
At any rate just use JSON with WebSockets. Its stupid simple and still 7-8x faster than HTTP with far less administrative overhead than either HTTP or gRPC.
- nevir 2y ago> because really it comes down to the frequency of data parsing into and out of the protobuf format. Protobuf is intentionally designed to NOT require any parsing at all. Data is serialized over the wire (or stored on disk) in the same format/byte order that it is stored in memory (Yes, that also means that it's not validated at runtime) Or are you referencing the code we all invariably write before/after protobuf to translate into a more useful format?
- sa46 2y agoYou’re likely thinking of Cap’n’Proto or flatbuffers. Protobuf definitely requires parsing. Zero values can be omitted on the wire so there’s not a fixed layout, meaning you can’t seek to a field. In order to find a fields value, you must traverse the entire message, and decode each tag number since the last tag wins.
- thinkharderdev 2y ago> Protobuf is intentionally designed to NOT require any parsing at all This is not true at all. If you have a language-specific class codegen'd by protoc then the in-memory representation of that object is absolutely not the same as the serialized representation. For example: 1. Integer values are varint encoded in the wire format but obviously not in the in-memory format 2. This depends on the language of course but variable length fields are stored inline in the wire format (and length-prefixed) while the in-memory representation will typically use some heap-allocated type (so the in-memory representation has a pointer in that field instead of the data stored inline)
- arp242 2y ago> Data is serialized over the wire (or stored on disk) in the same format/byte order that it is stored in memory That's just not true. You can read about the wire format over here, and AFAIK no mainstream language stores things in memory like this: https://protobuf.dev/programming-guides/encoding https://protobuf.dev/programming-guides/encoding I've had to debug protobuf messages, which is not fun at all, and it's absolutely parsed.
- cstrahan 2y ago> Protobuf is intentionally designed to NOT require any parsing at all. As others have mentioned, this is simply not the case, and the VARINT encoding is a trivial counterexample. It is this required decoding/parsing that (largely) distinguishes protobuf from Google's flatbuffers: https://github.com/google/flatbuffers https://github.com/google/flatbuffers https://flatbuffers.dev/ https://flatbuffers.dev/ Cap'n Proto (developed by Kenton Varda, the former Google engineer who, while at Google, re-wrote/refactored Google's protobuf to later open source it as the library we all know today) is another example of zero-copy (de)serialization.
- leetharris 2y ago> At any rate just use JSON with WebSockets. Its stupid simple and still 7-8x faster than HTTP with far less administrative overhead than either HTTP or gRPC. gRPC is not supposed to be a standard web communication layer. There are times where you need a binary format and extremely fast serialization/deserialization. Video games are one example where binary formats are greatly preferred over JSON. But I do agree that people keep trying to shove gRPC (or similar) into things where they aren't needed.
- anon291 2y agoDepending on the use case, it's often better to just copy structs directly, with maybe some care for endianness (little-endian). But at this point, the two most popular platforms, ARM and x86, agree on endianness and most alignment. There's almost no reason why RPC should not just be send(sk, (void *)&mystruct, sizeof(struct mystructtype), 0)
- hot_gril 2y agoWon't work if your struct has any pointers in it.
- anon291 2y agoI'd recommend not doing that then. Of course the same is true if you coerce a pointer to an int64 and store it in a protobuf.
- hot_gril 2y agoIt's not the pointers themselves so much as what they're typically used for. How would you do dynamic sizing? Imagine sending just a struct of integer arrays this way, you'd have to either know their sizes ahead of time or just be ok with sending a lot of empty bits up to some max size. And recursive structures would be impossible. You could get around this with a ton of effort around serdes, but it'd amount to reinventing ASN1 or Protobuf.
- kentonv 2y ago> Google claims gRPC with protobuf yields a 10-11x performance improvement over HTTP. That... doesn't make any sense, since gRPC is layered on top of HTTP. There must be missing context here.
- randomdata 2y agogRPC was based on a HTTP draft that predated the standardization of HTTP/2, so presumably that statement was said about HTTP/1. HTTP/2 may not have existed at the time it was asserted.
- lanstin 2y agogRPC gives you multiplexing slow request over 1 TCP connection, which reduces all the work and memory related to 1 socket per pending request; gRPC means you don't have to put the string name of a field into the wire, which makes your messages smaller which puts less stress into the memory system and the network, assuming your field values are roughly as large as your field names.
- randomdata 2y agoMultiplexing is a HTTP/2 feature. But as gRPC was based on an early HTTP/2 draft, it beat HTTP/2 to the punch. Thus it is likely that HTTP/2 didn't exist at the time the statement was made and therefore HTTP/1 would have been implied.
- hot_gril 2y agoMust be comparing to the equivalent JSON-over-HTTP usage.
- perezd 2y agoProtobuf can typically be about 70-80% smaller than the equivalent JSON payloads. If you care about Network I/O costs (at a large scale), you'd probably want to realize a benefit in cost savings like that. Additionally, I think people put a lot of trust into JSON parsers across ecosystems "just working", and I think that's something more people should look into (it's worse than you think): https://seriot.ch/projects/parsing_json.html https://seriot.ch/projects/parsing_json.html
- hot_gril 2y agoI agree, there's a lot to gain from getting away from JSON, but gRPC needs HTTP/1 support and better tooling to make that happen.
- perezd 2y agoYou probably want to check this out: https://connectrpc.com/ https://connectrpc.com/
- hot_gril 2y agoThanks. I've got a little project that needs to use protobufs, and if my DIY approach of sending either application/octet-stream or application/json turns out to be too sketchy, I'll give Connect a try. Only reason I'm not jumping for it is it involves more dependencies.
- austin-cheney 2y agoLet's say I wanted to transfer a movie in MKV container format. Its binary and large at about 4gb. Would I use JSON for that? No. Would I use gRPC/protobuf for that? No. I would open a dedicated TCP socket and a file system stream. I would then pipe the file system stream to the network socket. No matter what you still have to deal with packet assembly because if you are using TLS you have small packets (max size varies by TLS revision). If you are using WebSockets you have control frames and continuity frames and frame head assembly. Even with that administrative overhead its still a fast and simple approach. When it comes to application instructions, data from some data store, any kind of primitive data types, and so forth I would continue to use JSON over WebSockets.
- doctorpangloss 2y ago> JSON with WebSockets. Its stupid simple and still 7-8x faster than HTTP with far less administrative overhead than either HTTP or gRPC. Everyone doing what you are saying ends up reinventing parts of gRPC, on top of reinventing parts of RabbitMQ. It isn't ever "stupid simple." There are ways to build the things you need in a tightly coupled and elegant way, but what people want is Next.js, that's the coupling they care about, and it doesn't have a message broker (neither does gRPC), and it isn't a proxy (which introduce a bajillion little problems into WebSockets), and WebSockets lifetimes don't correspond to session lifetimes, so you have to reinvent that too, and...
- austin-cheney 2y agobut what people want is Next.js, What people? Developers? This is why I will not do that work anymore. Don't assume to know what I want based upon some tool set or tech stack that you find favorable. I hate (HATE HATE) talk of tech stacks, the fantasy of the developer who cannot write original software, who does not measure things, and cannot provide their own test automation. They scream their stupidity for all the world to hear when they start crying about reinventing wheels, or some other empty cliche, instead of just delivering a solution. What I want is two things: 1. Speed. This is not an assumption of speed. Its the result of various measurements in different execution contexts. 2. Less effort. I want to send a message across a network... and done. In this case you have some form of instruction or data package and then you literally just write that to the socket. That is literally 2 primitive instructions without abstractions like ex: socket.write(JSON.parse(thing));. It is without round trips, without headers, without anything else. You are just done.
- ranger207 2y ago> parts of The counterpoint to the fact that gRPC and RabbitMQ handle whatever you're writing better than you do is that gRPC and RabbitMQ have immense amounts of complexity that you have to deal with despite the fact that you don't care about it
- jakjak123 2y agoI dont even care about the performance. I just want some way to version my messages that is backward and forwards compatible and can be delivered in all the languages we use in production. I have tried to consume json over websockets before and its always a hassle with the evolution of the data format. Just version it in protobuf and push the bytes over websocket if you have a choice. Also, load balancing web socket services can be a bitch. Just rolling out our web socket service would disconnect 500k clients in 60 seconds if we didnt make huge amounts of work.
- dbmikus 2y agoTo get feature parity, you still need an IDL to generate types/classes for multiple languages. You could use JSON Schema for that. Websockets do not follow a request/reply semantics, so you'd have to write that yourself. I'd prefer not to write my own RPC protocol on top of websockets. That said, I'm sure there are some off the shelf frameworks out there, but do they have the same cross-language compatibility as protobuf + gRPC? I don't think "just use JSON with websockets" is such a simple suggestion. Of course, gRPC does have some of its own problems. The in-browser support is not great (non-existent without a compatibility layer?) last time I checked.