Live data from Hacker News

gRPC: The Bad Parts

kmcd.dev

101–110 of 230 posts

Re: gRPC: The Bad Parts

#101

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.

> 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…

That's great, but protobufs is slow as shit. I wouldnt use it in games.

If I was using something slow that needed flexibility I'd probably go with Avro since it has more powerful scheme evolution.

If I wanted fast I'd probably use SBE or Flatbuffers (although FB is also slow to serialise)

Re: gRPC: The Bad Parts

#102
post #97
post #37

Re. bad tooling. grpcurl[1] is irreplaceable when working with gRPC APIs. It allows you to make requests even if you don't have the .proto around. [1]: https://github.com/fullstorydev/grpcurl

> make requests even if you don't have the .proto around Like this? > grpcurl -d '{"id": 1234, "tags": ["foo","bar"]}' \ grpc.server.com:443 my.custom.server.Service/Method How is that even possible? How could grpcurl know how to translate your request to binary?

If I recall correctly, ProtoBuf has a reflection layer, and it's probably using that.

Re: gRPC: The Bad Parts

#103
post #67

Earlier quoted context omitted.

I'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.

It'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 reinv…

A lot of protocols in low latency trading systems just have fixed maximum size strings and will right pad with NUL or ASCII space characters.

Packed structs with fixed size fields, little endian integers and fixed point is heaven to work with.

Re: gRPC: The Bad Parts

#104

We use the textproto format extensively at work; it's super nice to be able to define tests of your APIs by using .textpb inputs and golden .textpb outputs. We have so many more tests using this method than if we manually called the APIs by in a programming language for each test case, and I wouldn't want to use JSON for test inputs, since it lacks comments.

Author here: Sorry that I was so harsh on textproto. You are right that it has some strengths over JSON... I'm actually a fan of JSONC for this reason. It does limit you on tooling... but so does textproto, right?

I think the bigger thing that I'm worried about is that gRPC has so many mandatory features that it can become hard to make a good implementation in new languages. To be honest there are some languages where the gRPC implementation is just not great and I blame the feature bloat... and I think textproto was a good demonstration of that feature bloat to me.

Re: gRPC: The Bad Parts

#105
post #36

Earlier quoted context omitted.

Depending 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)

Do all of your platforms have the same word width? The same -fshort-enums settings? Do you know that none of your data structures include pointers? Do all of your systems use the same compiler? Compiler version? I agree it will usually work, but this becomes an ABI concern, and it's surprisingly common to have ABI mismatches on one platform with the items I've noted above.

I've seen wire protocols that had junk for the alignment buffering in such structs. And I've seen people have to do a whole lot of work to make the wire protocol work on a newer compiler/platform. Also, the whole point of a network protocol being documented is that it decouples the interface (msgs over a network) from the implementation (parsing and acting on msgs). Your v1 server might be able to just copy the read buffer into a struct, but your v2 server won't. And it is possible and desirable to live in a world where you can change your implementation but leave your interface alone (although some parts of the software ecosystem seem to not know this nice fact and implicitly fight against realizing it).

My issue with gRPC is simple, the Go gRPC server code does a lot of allocations. I have a gRPC service where each container does 50-80K/second of incoming calls and I spend a ton of time in GC and in allocating headers for all the msgs. I have a similar REST service where I use fasthttp with 0 allocs (but all the stupidly high number of connections due to the lack of multiplexing thru the connection).

Re: gRPC: The Bad Parts

#106
post #34

Earlier quoted context omitted.

> 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.

gRPC 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.

gRPC 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.

Re: gRPC: The Bad Parts

#107

All good points. But I'd argue that the single worst part of gRPC is the impenetrability of its ecosystem. And I think that, in turn, is born of complexity. The thing is so packed with features and behaviors and temporal coupling and whatnot that it's difficult to produce a compatible third-party implementation. That means that, in effect, the only true gRPC implementation is the one that Google maintains. Which, in…

It is possible to do quite well, as demonstrated by .NET. Edit: and, if I remember correctly, gRPC tooling for it is maintained by about 1-3 people that are also responsible for other projects, like System.Text.Json. You don't need numbers to make something that is nice to use, quite often, it makes it more difficult even.

No disrespect to the other developers on the team, but James Newton-King is no ordinary developer.

Re: gRPC: The Bad Parts

#108

All good points. But I'd argue that the single worst part of gRPC is the impenetrability of its ecosystem. And I think that, in turn, is born of complexity. The thing is so packed with features and behaviors and temporal coupling and whatnot that it's difficult to produce a compatible third-party implementation. That means that, in effect, the only true gRPC implementation is the one that Google maintains. Which, in…

> But I'd argue that the single worst part of gRPC is the impenetrability of its ecosystem

I have had the opposite experience. I visit exactly two repositories on GitHub, which seem to have the vast majority of the functionality I need.

> The thing is so packed with features and behaviors and temporal coupling and whatnot that it's difficult to produce a compatible third-party implementation.

Improbable did. But who cares? Why do we care about compatible third party implementations? The gRPC maintainers merge third party contributions. They care. Everyone should be working on one implementation.

> features arguably have a poor cost/benefit tradeoff for anyone who isn't trying to solve Google problems.

Maybe.

We need less toil, less energy spent reinventing half of Kubernetes and half of gRPC.

Re: gRPC: The Bad Parts

#109
post #53

The tooling around gRPC with bazel when using python is so bad it’s almost impossible to work with, which is hilarious considering they both come from Google. Then I had additional problems getting it to work with Ruby. Then I had more problems getting it to work in k8s, because of load balancing with http/2. Combine those issues with a number of other problems I ran into with gRPC, and I ended up just building a sma…

Another point of view is, don't use Bazel. In my experience, Gradle is less of a headache and well supported.

Re: gRPC: The Bad Parts

#110

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.

> 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…

> gRPC is not supposed to be a standard web communication layer.

It kind of is. What do you think WebTransport in HTTP/3 is? It's basically gRPC Next. The only reason gRPC didn't make it as the standard web communication layer is because of one disastrous decision by one Chrome engineer in https://issues.chromium.org/issues/40388906, maybe because he woke up on the wrong side of the bed.

Post reply on HN