gRPC Makes the Most Sense Inside Service Boundaries_
gRPC is compelling for internal services because it gives you strict contracts, code generation, and efficient transport, but it is not a universal replacement for REST.
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.