gRPC as a Transport
A binary contract-first RPC protocol over HTTP/2 — efficient and strongly typed for internal service-to-service calls, awkward at the browser edge.
Definition
gRPC defines services and messages in a schema, generates client and server code in many languages, and transports binary-encoded messages over HTTP/2 with multiplexed streams.
Where it wins
- Internal service-to-service calls in a polyglot estate. The generated client removes an entire category of integration bug, and the schema is the contract rather than a document describing one.
- Payload efficiency. Binary encoding is substantially smaller than JSON, which matters at high call volume and on constrained networks.
- Streaming. Server, client and bidirectional streaming are first-class, not bolted on.
- Contract evolution with real rules. Field numbers, reserved fields and clear compatibility semantics make additive change safe and breaking change obvious.
Large polyglot estates — Uber-scale service counts across several languages — adopt it substantially for the generated-client property. When thousands of services call each other, hand-written clients per language per service is not a maintenance burden anyone survives, and the schema registry becomes the organisation's actual API documentation.
Where it is awkward
- Browsers. Browsers cannot speak gRPC natively; a proxy translation layer is required. For a public API consumed by web clients, this is friction with little payoff.
- Debuggability. You cannot read a binary payload in a log or reproduce a call with curl without tooling. Teams underestimate how much day-to-day productivity comes from that.
- Third-party integration. Partners expect REST and JSON. Offering gRPC externally narrows your integrator pool.
- Load balancing. Long-lived HTTP/2 connections multiplex many requests, so connection-level layer 4 balancing pins all of a client's calls to one backend. Request-level (layer 7) balancing or client-side balancing is required, and getting this wrong produces badly skewed backend load that is easy to miss.
Failure scenarios
- Layer 4 balancing in front of gRPC, so backends are unevenly loaded and adding instances does not help.
- Breaking schema change — reusing a field number, changing a type — which fails at runtime rather than at compile time for already-deployed clients.
- Deadlines not propagated, losing the main resilience benefit the protocol offers.
- Adopted for a public API and then wrapped in a REST gateway anyway, paying both costs.
Trade-offs
Bought: type safety, efficiency, streaming, generated clients, disciplined contract evolution. Sold: human readability, browser compatibility, ease of ad-hoc debugging, and simplicity of load balancing.
The common and correct outcome: gRPC internally, REST and JSON at the public edge.
Interview question
"You put a layer 4 load balancer in front of a gRPC service and one backend receives most of the traffic. Why?"