gRPC: The Bad Parts

gRPC, Google’s high‑performance RPC framework built on HTTP/2 and Protocol Buffers, is praised for strong typing and cross‑language code generation but criticized as overly complex, hard to debug, and poorly tooled in many languages. Commenters highlight issues such as convoluted generated code, fragile build and versioning workflows, HTTP/2 and trailer reliance that limits browser and legacy platform support, and protobuf design quirks like optional fields. Many argue that simpler JSON/HTTP or WebSockets are sufficient for most use cases, while others see value in gRPC’s contracts when paired with newer tooling like Buf and ConnectRPC that aim to fix its rough edges.

Tooling and Developer Experience

  • Many find core tooling clunky: manual protoc wiring (esp. in Go), weak integration with build systems like Bazel, and confusing config via JSON strings in some languages.
  • Others report excellent workflows in ecosystems with first-class integration (notably .NET/C# and some Java setups), where proto compilation is wired into the build and “just works.”
  • grpcurl and GUI tools (e.g., Kreya) are highlighted as essential for debugging; some still prefer writing small custom CLIs.
  • Buf is repeatedly cited as significantly improving proto dependency management, packaging, linting, and codegen.

Language Implementations and API Quality

  • Implementations vary widely: C# and Java often praised; Go’s gRPC/protobuf stack is criticized as ergonomically and performance-poor; C++ bindings are seen as over-abstracted and even encouraging anti-patterns.
  • Python and Ruby users report missing features or fragile integrations; protobuf version pinning across dependencies is a recurring pain.

Protobuf Semantics and Versioning

  • Proto3’s “everything optional, default values everywhere” design is contentious. Critics dislike not distinguishing “unset” from “default”; supporters say required fields made evolution impossible and nullability is overused.
  • Later proto3 additions (optional primitives, presence checks, annotations like field_behavior) partly address this but remain inconsistent across languages.
  • Proto file versioning and lack of a canonical proto package manager (beyond Buf) are seen as real gaps.

Transport, HTTP/2, and Web/Browsers

  • Heavy reliance on HTTP/2 and trailers is viewed as a major design misstep, especially for browsers, certain runtimes (e.g., game engines), and some platforms that still lack HTTP/2.
  • gRPC-Web and HTTP/1 compatibility layers exist but add complexity; some wish for a native HTTP/1 mode or WebSocket/WebTransport-based design.

Complexity, Overuse, and Suitability

  • Many argue most projects don’t need gRPC and pay unnecessary complexity versus simple JSON/REST or JSON-over-WebSockets.
  • Fans emphasize strong typing, shared IDL, smaller payloads, multiplexing, and easier multi-language stubs compared to ad-hoc REST/OpenAPI ecosystems.
  • There’s concern that feature bloat and ecosystem impenetrability make independent implementations hard and tie users to “the official” stack.

Alternatives and Variants

  • ConnectRPC plus Buf (and protovalidate) are repeatedly praised as “gRPC done right,” with better HTTP/1 support, simpler semantics, and good tooling while remaining interoperable with gRPC.
  • Other options mentioned: JSON-RPC, Thrift, NATS-based RPC, MessagePack, FlatBuffers/Cap’n Proto, and custom binary protocols for niche high-performance or low-latency domains.