gRPC Basics
Table of Contents + −
Picture a food delivery app like Uber Eats. When Riya places an order, that one tap kicks off a lot of quiet chatter in the background. Like, the order service has to ask the payment service “did the money go through?”, then ask the restaurant service “can you cook this?”, then ask the delivery service “who’s nearby?”. So here’s the thing:
- These are separate services, and they talk to each other constantly.
- This chatter happens millions of times a day, deep inside the system.
- It has to be fast, because the user is sitting there waiting for the screen to move.
Now, you already know REST for this kind of talking. But for service-to-service chatter at this scale, REST starts to feel slow and heavy. That’s the problem gRPC was built to solve. Let’s see how.
🎯 What is gRPC
Let’s get the name out of the way first. gRPC stands for Remote Procedure Call, and the “g” came from Google, who built it.
Here’s the simple idea:
- A Remote Procedure Call means one service calls a function that actually lives on another service, across the network, as if that function were sitting right there in its own code.
- So instead of Riya’s order service thinking “let me send an HTTP request to the payment service”, it just calls
checkPayment(orderId)like a normal function. gRPC handles all the network stuff in the background. - It feels local, but it runs remote. That’s the whole trick.
So gRPC is a way for services to call each other’s functions quickly over the network, hiding the messy network details from you.
REST is talking, gRPC is calling
With REST you think in terms of sending a request to a URL. With gRPC you think in terms of calling a function. Same goal (one service talking to another), but gRPC makes it feel like ordinary code.
🤔 Why Not Just Use REST
REST is great, and you should still use it for public APIs. But deep inside a system, where services talk to each other all day, REST has some real costs. Here’s what starts to hurt:
- JSON is heavy. REST usually sends data as JSON text. Text is easy for humans to read, but it’s big, and the computer has to spend time reading and parsing all those words and brackets.
- No strict contract. With REST, nothing stops one team from quietly changing a field name. The other service only finds out when something breaks.
- One request at a time, mostly. Plain REST isn’t built for a constant two-way stream of data. You ask, you get an answer, done.
gRPC fixes each of these. It sends data in a small binary format, it forces a strict shared contract, and it supports streaming. Let’s see how it pulls that off.
⚙️ How gRPC Works
gRPC stands on two pieces of technology. Knowing just these two is enough to understand the whole thing.
- Protocol Buffers (Protobuf). This is how gRPC packs data. Instead of JSON text, it turns your data into a small binary format that’s fast to send and fast to read. (Binary just means the compact computer format, not human-readable text.)
- HTTP/2. This is the newer version of HTTP that gRPC travels on. It can keep one connection open and send many messages over it at once, in both directions. That’s what makes streaming possible.
The starting point is a file called a .proto file. In it, you describe two things: the messages (the shape of your data) and the service (the functions you can call). Here’s a small one for our payment example.
// payment.proto — the shared contract between services
// The data we send inmessage PaymentRequest { string order_id = 1; int32 amount = 2;}
// The data we get backmessage PaymentResponse { bool success = 1; string message = 2;}
// The functions this service offersservice PaymentService { rpc CheckPayment(PaymentRequest) returns (PaymentResponse);}Let’s read that top to bottom, because every line is doing a job.
message PaymentRequestdescribes the data going in: anorder_idand anamount. The numbers (= 1,= 2) are just fixed tags for each field, so both sides always agree on the order.message PaymentResponsedescribes what comes back: asuccessflag and a shortmessage.service PaymentServicelists the functions. Here there’s one,CheckPayment, which takes aPaymentRequestand returns aPaymentResponse.
From this one file, gRPC auto-generates code (called stubs) for both the caller and the receiver. A stub is the helper code that does the real network work for you. So the calling service just writes:
response = paymentService.CheckPayment(order_id="OD123", amount=499)if response.success: # move the order forwardNo URLs, no JSON, no parsing. It looks like a plain function call, and the stub quietly handles the network underneath.
🏗️ The Call Flow
So what actually happens when one service calls another with gRPC? Let’s walk one round trip, step by step.
Reading that left to right:
- The order service calls
CheckPayment()like a normal function. - The client stub packs the request into the small Protobuf binary format.
- It travels over the open HTTP/2 connection to the payment service.
- The server stub unpacks it, the real function runs, and the answer comes back the same way.
The key point: all the packing, sending, and unpacking is hidden. You write a function call, gRPC does the rest.
📊 gRPC vs REST
Here’s a side-by-side so the trade-offs are clear. Neither one wins everywhere, they’re built for different jobs.
| Point | REST | gRPC |
|---|---|---|
| Data format | JSON text (bigger) | Protobuf binary (smaller, faster) |
| Travels on | HTTP/1.1 usually | HTTP/2 |
| Contract | Loose, often just docs | Strict, defined in .proto |
| Streaming | Limited | Built in, both directions |
| Works in browsers directly | Yes | No (needs gRPC-Web) |
| Best for | Public APIs, browser apps | Internal service-to-service |
🔁 The Four Ways gRPC Can Talk
Because gRPC sits on HTTP/2, it can do more than just ask-and-answer. There are four styles, and the names say what they do:
- Unary is the normal one: one request, one response. Like our
CheckPaymentexample. - Server streaming means one request, then the server sends back a stream of responses. Good for “give me live updates on this order”.
- Client streaming means the client sends a stream of data, then gets one answer. Good for uploading lots of small readings at once.
- Bidirectional streaming means both sides send streams at the same time over the one connection. Good for a live chat between services.
You don’t need to memorize these now. Just know gRPC isn’t stuck with one-question-one-answer like plain REST is.
🌍 Where gRPC Is Used
gRPC really shines inside large systems with many services. A few real places:
- Google uses it everywhere internally, since they created it for exactly this problem.
- Netflix and Uber use gRPC for fast communication between their internal microservices.
- It’s a common default in Kubernetes based systems, where lots of small services need to talk quickly.
Notice the pattern: it’s almost always service-to-service, inside the system, not the part the browser talks to.
⚠️ Common Mistakes and Misconceptions
A few ideas trip people up when they first meet gRPC. Let’s clear them up:
- “gRPC will replace REST.” No. They live together. Most systems use REST for the public-facing API the browser hits, and gRPC for the fast internal chatter behind it.
- “The browser can call gRPC directly.” Not on its own. Browsers can’t speak raw gRPC, so you need a layer called gRPC-Web in between. This is a big reason public APIs stay on REST.
- “Binary means it’s complicated to use.” The binary part is hidden from you. You write a normal function call, the stub handles the binary packing. You rarely see it.
Don't reach for gRPC on day one
If you’re building a small app or a simple public API, REST is easier and works fine. gRPC pays off when you have many services talking to each other a lot, and speed between them really matters. Match the tool to the need.
🧩 What You’ve Learned
Nice, that’s a solid first look at gRPC. Here’s the recap:
- ✅ gRPC lets one service call another service’s function over the network, as if it were a local call.
- ✅ It’s fast because it uses Protocol Buffers (small binary data) and HTTP/2 (one open connection, many messages).
- ✅ You define the data and functions in a .proto file, and gRPC generates the client and server stubs for you.
- ✅ It supports four styles: unary, server streaming, client streaming, and bidirectional streaming.
- ✅ Use gRPC for fast internal service-to-service talk, and stick with REST for public, browser-facing APIs.
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
What does gRPC use to pack data, instead of JSON text?
Why: gRPC uses Protocol Buffers (Protobuf), a compact binary format that's faster to send and read than JSON text.
- 2
Why can't a browser use gRPC directly?
Why: Browsers can't speak raw gRPC over HTTP/2, so you add a gRPC-Web layer. This is a big reason public APIs stay on REST.
- 3
When is gRPC the better choice over REST?
Why: gRPC shines for fast service-to-service calls inside a system, like microservices. Public, browser-facing APIs usually stay on REST.
- 4
What does a .proto file define?
Why: A .proto file is the shared contract: it defines the data (messages) and the functions (service). gRPC uses it to generate the client and server stubs.
🚀 What’s Next?
You’ve now seen the fast, internal way services talk. Let’s connect it to what you already know.
- REST APIs Explained is the public-facing style gRPC works alongside.
- WebSockets Explained is another way to keep a live, two-way connection open.
Get these three down (REST, gRPC, and WebSockets) and you’ll be able to pick the right way for services to talk in almost any design.