Why RPC, and Why gRPC

REST won the public web, but inside a system — between the dozens of services that make up a modern backend — a different model dominates: RPC. Instead of modeling everything as resources and verbs over HTTP, you call a remote function as if it were local. gRPC is the modern, high-performance realization of that idea, built on Protocol Buffers and HTTP/2. Understanding why it exists explains when to reach for it over REST.

Most engineers meet REST first and assume it’s the only way services talk. It isn’t. For internal, service-to-service communication — the chatty, high-volume traffic between your own backend components — remote procedure calls are often the better fit, and gRPC is the framework that made RPC fast, typed, and pleasant. This series builds gRPC and Protocol Buffers from the ground up. This first post is about the why: what problem RPC solves and what gRPC brings to it.

The RPC idea

Remote procedure call is a decades-old idea with a simple pitch: calling a function on another machine should feel like calling one locally. You write user := client.GetUser(ctx, &GetUserRequest{Id: 42}) and it looks and reads like an ordinary method call — but under the hood the arguments are serialized, sent over the network, executed on a remote server, and the result is sent back and deserialized into a return value.

The point is abstraction. All the mechanics — serialization, framing, transport, error propagation — are hidden behind a generated function signature. You think in terms of operations (“get this user,” “charge this card,” “stream these events”), not in terms of HTTP methods, URL paths, status codes, and JSON shapes you assemble by hand. For internal APIs where both sides are yours, that operation-centric model often maps far more naturally to what you’re actually doing than REST’s resource-centric one.

What gRPC is

gRPC is Google’s open-source RPC framework, and it’s really the combination of three well-chosen pieces:

The result is a system where you write an interface once, generate strongly-typed code for every language you use, and get efficient binary communication for free. The .proto contract is the heart of it — everything else is generated from it.

Where gRPC beats REST

gRPC’s advantages come directly from those three pieces, and they matter most for internal, high-traffic APIs:

Where REST still wins

gRPC is not a universal replacement, and pretending otherwise leads to using it in the wrong places. REST remains the better choice when:

The clean rule of thumb: gRPC for internal service-to-service traffic where performance, typed contracts, and streaming matter; REST for public, browser-facing, or human-explored APIs. Many systems use both — gRPC between internal services, a REST/JSON gateway at the public edge.

The mental model for the series

Everything in gRPC flows from one artifact: the .proto file. It defines your messages (the data structures) and your services (the callable methods), and from it the toolchain generates the typed stubs both sides use. Master that contract and its generated code, and the rest — the four call types, deadlines, errors, streaming, production concerns — are layers on top.

So the series proceeds bottom-up: Protocol Buffers and the wire format (post 2), the four kinds of RPC (post 3), how code generation and stubs work (post 4), deadlines/metadata/interceptors (post 5), error handling (post 6), streaming and backpressure in depth (post 7), and running gRPC in production (post 8). By the end, RPC will feel like what it’s meant to be — calling a function that happens to live on another machine — with none of the mechanics hidden from your understanding.

Key takeaways

Further reading

Sources & References

What gRPC is and why RPC