If you are early in backend engineering, gRPC can feel intimidating.
The words around it sound heavy:
- Protocol Buffers
- HTTP/2
- unary RPC
- streaming
- code generation
- service contracts
But the core idea is not that complicated.
gRPC is a way for one service to call another service like a normal function, even though both services are running on different machines.
Instead of thinking:
send HTTP request to /users/123
parse JSON response
manually map fieldsgRPC wants you to think:
userService.GetUser({ id: "123" })That is the main mental model.
It makes remote service calls feel closer to normal function calls, while still going over the network.
1. Why do we need gRPC at all?
Most developers learn REST first.
REST is easy to understand:
GET /users/123
POST /orders
PUT /products/42
DELETE /sessions/currentThis works well for many systems. But as services grow, teams start facing problems:
- different services disagree on request/response shape
- JSON payloads become large
- API contracts are not strict enough
- clients duplicate request-building logic
- service-to-service calls need better performance
- streaming use cases are awkward over normal REST
gRPC was built to solve many of these problems.
It gives you:
- strongly defined service contracts
- generated client and server code
- efficient binary payloads
- HTTP/2 support
- built-in support for streaming
That is why gRPC is common in microservices, internal platform systems, service mesh control planes, and high-performance backend communication.
2. The simplest gRPC mental model
Imagine you have two services:
order-service
payment-serviceWhen someone places an order, order-service needs to ask payment-service to charge the customer.
In REST, order-service might call:
POST /payments/chargewith JSON:
{
"orderId": "ord_123",
"amount": 999,
"currency": "INR"
}In gRPC, you define a service method:
service PaymentService {
rpc Charge(ChargeRequest) returns (ChargeResponse);
}Then your code calls it like a method:
const response = await paymentClient.charge({
orderId: "ord_123",
amount: 999,
currency: "INR",
});Behind the scenes, it still sends data over the network.
But for the developer, the contract is clearer and the client code is generated from the service definition.
3. What are Protocol Buffers?
Protocol Buffers, usually called protobuf, are the default data format used by gRPC.
Think of protobuf as a strict schema for your API messages.
In REST, you often send JSON like this:
{
"id": "user_123",
"name": "Rahul",
"age": 28
}JSON is human-readable, but it does not enforce a strict type contract by itself.
With protobuf, you define the shape first:
message User {
string id = 1;
string name = 2;
int32 age = 3;
}That file says:
idmust be a stringnamemust be a stringagemust be an integer
The numbers 1, 2, and 3 are field tags. They are used in the binary encoding. They are not default values.
This is important because protobuf is not just a documentation format. It is used to generate code.
From one .proto file, you can generate:
- Go structs
- Java classes
- TypeScript types
- Python classes
- client code
- server interfaces
That is one of the biggest benefits of gRPC.
The contract becomes a source of truth.
4. Why protobuf is faster than JSON
JSON is text.
Protobuf is binary.
That means protobuf messages are usually:
- smaller on the wire
- faster to parse
- stricter in type handling
- better for service-to-service communication
Example JSON:
{
"id": "user_123",
"name": "Rahul",
"age": 28
}JSON includes field names like "id", "name", and "age" every time.
Protobuf uses numeric field tags internally, so it does not need to send full field names repeatedly.
That saves space and parsing work.
This does not mean JSON is bad. JSON is excellent for public APIs, debugging, browsers, and human-readable payloads.
But for backend-to-backend communication, protobuf is often more efficient.
5. What does HTTP/2 have to do with gRPC?
gRPC usually runs over HTTP/2.
HTTP/2 gives gRPC useful features:
- multiplexing multiple requests over one connection
- better connection reuse
- binary framing
- support for streaming
- lower overhead for many service-to-service calls
You do not need to understand every HTTP/2 detail at the start.
Just remember this:
- REST commonly uses HTTP with JSON
- gRPC commonly uses HTTP/2 with protobuf
That combination makes gRPC a strong fit for internal high-performance service communication.
6. The four types of gRPC calls
gRPC is not only request-response.
It supports four call styles.
7. Unary RPC
Client sends one request. Server sends one response.
client -> request -> server
client <- response <- serverExample:
rpc GetUser(GetUserRequest) returns (User);Use this for normal service calls like:
- get user
- create order
- verify payment
- fetch config
This is the gRPC style most similar to REST.
8. Server streaming
Client sends one request. Server sends many responses.
client -> request -> server
client <- item 1
client <- item 2
client <- item 3Example:
rpc WatchOrders(WatchOrdersRequest) returns (stream OrderEvent);Use this when the client wants to keep receiving updates:
- live order status
- logs
- notifications
- config updates
9. Client streaming
Client sends many messages. Server sends one response.
client -> item 1
client -> item 2
client -> item 3
client <- final responseExample:
rpc UploadMetrics(stream Metric) returns (UploadSummary);Use this when the client needs to upload many items efficiently:
- metrics
- logs
- file chunks
- sensor data
10. Bidirectional streaming
Both client and server can send messages continuously.
client <-> serverExample:
rpc Chat(stream ChatMessage) returns (stream ChatMessage);Use this for:
- chat systems
- live collaboration
- real-time control channels
- long-running data sync
This is one of the places gRPC feels much stronger than normal REST.
11. gRPC vs REST
REST is resource-oriented.
You think in URLs:
GET /users/123
POST /ordersgRPC is action/service-oriented.
You think in methods:
rpc GetUser(GetUserRequest) returns (User);
rpc CreateOrder(CreateOrderRequest) returns (Order);Both can solve many of the same problems, but they optimize for different things.
12. REST pros
REST is great because:
- easy to learn
- works naturally in browsers
- easy to test with curl/Postman
- JSON is human-readable
- great for public APIs
- caching with HTTP semantics is straightforward
- many developers already understand it
If you are building an API for external developers, REST is often the safest default.
13. REST cons
REST can become painful when:
- contracts are loosely enforced
- clients manually duplicate types
- payloads are large
- service-to-service communication is very frequent
- streaming is needed
- different teams interpret API structure differently
REST can be excellent, but large systems need discipline around schemas, versioning, and documentation.
14. gRPC pros
gRPC is strong because:
- service contracts are explicit
- client/server code can be generated
- protobuf payloads are compact
- type safety is better
- streaming is built in
- service-to-service performance is usually strong
- good fit for internal microservices
If two backend services talk frequently, gRPC can be a very good choice.
15. gRPC cons
gRPC also has real downsides:
- harder to debug by just reading payloads
- not as browser-friendly as REST without extra tooling
.protogeneration adds build complexity- teams must understand schema evolution
- public API consumers may find REST easier
- some infrastructure tools are more HTTP/JSON-friendly
The biggest beginner mistake is assuming gRPC is automatically better because it is faster.
It is not automatically better.
It is better when its tradeoffs fit the system.
16. gRPC vs GraphQL
GraphQL solves a different problem.
GraphQL is mainly about letting clients ask for exactly the data they need.
Example:
query {
user(id: "123") {
name
orders {
id
total
}
}
}This is very useful for frontend-heavy products where different screens need different data shapes.
gRPC is usually stronger for backend-to-backend service contracts.
So the comparison is not “which one is better?”
It is more like:
- GraphQL is client-query focused
- gRPC is service-contract focused
- REST is resource/API focused
17. GraphQL pros
GraphQL is useful because:
- clients choose exactly what fields they need
- avoids over-fetching and under-fetching
- good for complex frontend data requirements
- one endpoint can expose a rich graph of data
- strongly typed schema helps frontend/backend collaboration
It is often a great fit when product UI needs flexible data access.
18. GraphQL cons
GraphQL can become difficult because:
- caching is harder than simple REST caching
- query complexity can hurt performance
- authorization can become subtle
- backend resolvers may create N+1 query problems
- operating GraphQL safely needs guardrails
GraphQL gives clients power. That power needs limits.
19. When should you choose REST?
Choose REST when:
- you are building public APIs
- browser support matters
- human readability matters
- the API maps naturally to resources
- simple request-response is enough
- team familiarity matters more than raw efficiency
Example:
- public payment API
- user management API
- admin CRUD API
- partner integration API
REST is boring in the best possible way.
20. When should you choose gRPC?
Choose gRPC when:
- backend services call each other frequently
- strict contracts matter
- performance matters
- streaming is useful
- clients and servers are controlled by your organization
- you can manage protobuf generation cleanly
Example:
- internal microservices
- service mesh control planes
- low-latency backend systems
- high-throughput data pipelines
- real-time server communication
gRPC is excellent when the main consumers are other services, not random humans with curl.
21. When should you choose GraphQL?
Choose GraphQL when:
- frontend screens need flexible data shapes
- clients often need nested related data
- avoiding over-fetching matters
- multiple clients need different views of the same domain
Example:
- web/mobile app backend
- product dashboards
- content-heavy applications
- complex frontend aggregation layers
GraphQL is usually more about product data access than internal service performance.
22. Schema evolution: the part juniors should not ignore
With protobuf, you must be careful when changing messages.
This is safe:
message User {
string id = 1;
string name = 2;
int32 age = 3;
string email = 4;
}Adding a new field is usually okay.
This is dangerous:
message User {
string id = 1;
int32 name = 2;
}Changing the meaning or type of an existing field can break clients.
Basic protobuf rule:
- do not reuse field numbers
- do not casually change field types
- add new fields instead of changing old ones
- keep backward compatibility in mind
This is one of the most important habits when working with gRPC.
23. A simple decision table
| Use case | Best default |
|---|---|
| Public API for external users | REST |
| Internal service-to-service calls | gRPC |
| Frontend needs flexible nested data | GraphQL |
| Real-time server streaming | gRPC |
| Simple CRUD admin API | REST |
| Mobile app with varied screen data | GraphQL or REST |
| High-throughput backend pipeline | gRPC |
This table is not a law. It is a starting point.
24. The practical architecture pattern
Many mature systems use more than one API style.
For example:
mobile app -> GraphQL or REST -> backend-for-frontend
backend-for-frontend -> gRPC -> internal services
internal services -> gRPC -> other internal services
external partners -> REST -> public API gatewayThat is normal.
You do not need to force one protocol everywhere.
Use the right protocol at the right boundary.
25. The final mental model
If you remember only one thing:
- REST is great for simple, public, human-friendly APIs
- GraphQL is great when clients need flexible data selection
- gRPC is great for strongly typed, efficient service-to-service communication
- protobuf is the schema and binary message format that makes gRPC efficient and type-safe
gRPC is not magic.
It is a contract-first way to make services talk to each other efficiently.
Once that clicks, the rest becomes much less scary.
If you are a junior engineer learning gRPC, do not start by memorizing every streaming mode or HTTP/2 detail. Start by understanding .proto files, generated clients, and why strict contracts matter. That foundation will make everything else easier.