gRPC vs REST: Picking the Wire Protocol
Both are fine choices. Picking wrong costs you debugging, observability, and a year of regret.
gRPC vs REST is one of those forever-debates whose answer is genuinely it depends. Here is what it depends on, with the trade-offs that actually bite.
1. The two-line summary
- REST/JSON — human-readable, debuggable in a browser, cached by CDN, slower on the wire, schemaless by default.
- gRPC/protobuf — compact, fast, strongly typed via .proto files, streaming-friendly, opaque to most off-the-shelf tooling.
2. Where gRPC genuinely wins
2.1 Internal service-to-service
Inside a cluster, the protobuf serialisation overhead disappears against the savings. A typical microservice mesh pushing 10k RPS sees CPU drop noticeably on the wire-format alone.
2.2 Strongly typed contracts
The .proto file is the contract. Code-gen produces typed clients in every language. Adding a field is forward-compatible; removing one is a compile error before deploy. That kind of safety is hard to match in OpenAPI without discipline.
2.3 Streaming
gRPC has bidirectional streams as a first-class primitive. If you need a long-lived connection that pushes events both ways — telemetry, presence, transcription — gRPC is built for it. REST with Server-Sent Events or WebSockets gets there but with more glue.
3. Where REST genuinely wins
3.1 Public APIs
Your customers will hit your API with curl. They will paste responses into Slack. They will use Postman. JSON over HTTP is the lingua franca; gRPC is not. Maybe gRPC-web is an answer for browsers, but it is rarely the right answer for a public surface.
3.2 CDN cacheability
REST GETs cache. CloudFront, Fastly, Varnish — they all key on the URL and the cache-control headers. gRPC calls all look like POSTs to HTTP/2 and don't cache at the edge.
3.3 Browser-friendliness
From a browser, REST is one fetch. gRPC requires gRPC-web + a proxy (Envoy) to translate. That extra hop is a perfectly fine engineering decision but it is a hop.
3.4 Debuggability with off-the-shelf tools
You can tcpdump a REST call and read it. A protobuf payload requires the .proto file to decode. In a 3am incident, the readability gap matters.
4. The myths
"gRPC is faster"
Yes, sometimes 5–10× for high-throughput internal calls. No, almost never the bottleneck for typical CRUD endpoints. Don't pick gRPC for performance unless you have measured the JSON serialisation cost and it shows.
"REST is easier"
Until you ship a v2 of an endpoint, a client uses an unspecified field, you change validation, and three downstream teams scream. Versioning REST is its own discipline. gRPC handles that with reserved field numbers and explicit deprecation.
5. The hybrid pattern (what most teams end up at)
- Public API → REST + OpenAPI.
- Internal service mesh → gRPC + protobuf.
- Edge gateway translates REST → gRPC for browser/mobile clients.
This is what every large platform settles on after a year. You get JSON where it helps and protobuf where it helps.
6. Concrete checklist
- Will browsers call this directly? → REST.
- Is this an internal RPC between services you control? → gRPC, if you have the tooling. REST is still fine.
- Do you need streaming? → gRPC, or accept the WebSocket complexity.
- Does the team already know one and not the other? → use the one they know. Familiarity beats wire-format wins.