Teams usually adopt gRPC for one of two reasons.
The good reason is that they have a growing set of internal services and want a stricter, better-tooled contract than ad hoc JSON over HTTP. The bad reason is that they heard REST is "legacy" and want to replace every API without being clear about the problem they are solving.
gRPC is excellent in the first case. It is often unnecessary in the second.
What gRPC Actually Improves
For internal service-to-service calls, gRPC gives you a few meaningful advantages at the same time:
- a schema-first contract in
.proto files
- generated clients and servers
- compact binary serialization
- built-in streaming patterns
That combination reduces a lot of interface drift between services.
Here is the kind of contract that ages better than a loosely documented JSON shape:
syntax = "proto3";
service UserService {
rpc GetUser (GetUserRequest) returns (GetUserResponse);
}
message GetUserRequest {
string id = 1;
}
message GetUserResponse {
string id = 1;
string email = 2;
bool active = 3;
}
Once that schema exists, the contract stops living in Slack messages and half-updated wiki pages.
Where It Helps in Practice
The biggest win is usually not raw serialization speed. It is interface discipline.
If five services all need to talk to the same billing or identity service, generated clients and a stable schema reduce a lot of accidental breakage. You stop hand-writing payload types in every consumer and start treating the service boundary like a real product surface.
That matters more over time than shaving a few bytes off the wire.
Where REST Still Wins
REST still has strong advantages:
- it is easy to debug with common tools
- it works naturally with browsers
- it maps cleanly to public APIs
- it fits caching and HTTP semantics well
That is why many systems end up with a split model:
- REST or HTTP JSON at the edge
- gRPC inside the mesh
This is often the most pragmatic architecture.
The Trade-Offs
gRPC is not free.
You take on:
- protobuf schema management
- generated code in the toolchain
- less convenient inspection than plain JSON
- more friction for browser-native clients unless you add gRPC-Web or another bridge
That is fine when the environment is controlled. It is less fine when the API must be broadly consumable.
A Good Decision Rule
Use gRPC when:
- the callers are mostly internal services
- strong contracts matter
- you want generated clients across teams or languages
Stick with REST when:
- the API is public
- browsers are first-class consumers
- HTTP semantics and caching matter more than RPC ergonomics
The point is not to pick a winner for every system. The point is to stop using one protocol out of habit.
Further Reading