Skip to main content

REST vs RPC

REST vs. GraphQL compared two ways of exposing data to a client. RPC (Remote Procedure Call) is a different axis entirely: instead of modeling an API around resources, it models it around actions — calling a named function on a remote service feels, as much as possible, like calling a regular function in your own code.

REST: nouns and a fixed vocabulary of verbs

REST, covered in full in APIs and REST vs. GraphQL, models everything as a resource addressed by a URL, manipulated through a small, fixed set of HTTP methods (GET, POST, PUT, DELETE). This constraint is a genuine strength: because the vocabulary is small and standardized, REST responses plug directly into HTTP-native tooling — caching, standard status codes, off-the-shelf clients — with no custom protocol work.

RPC: naming the action directly

RPC skips the resource/verb constraint entirely and just calls a named remote procedure — getUser(id), chargeCard(amount, token), recalculateShippingCost(order) — that maps far more directly onto how the underlying code is actually structured. This tends to fit naturally when an operation doesn't cleanly map to "manipulate a resource" at all (recalculateShippingCost isn't really a GET, PUT, or DELETE on anything).

System Design Lab

Modern RPC: gRPC and the performance case

Modern RPC frameworks — gRPC being the dominant one — pair the action-oriented model with real performance advantages over typical REST-over-JSON: gRPC runs over HTTP/2 by default (multiplexed, no per-request connection overhead) and serializes messages as compact binary (Protocol Buffers) instead of text-based JSON, which is both smaller on the wire and faster to parse. This is why gRPC is a common default for internal service-to-service calls within a Microservices Architecture — every one of those calls' overhead compounds across potentially many hops in one request's journey, so shaving serialization and connection cost matters more there than it does for one browser-to-server call.

What RPC gives up for that performance

The tradeoff is real: gRPC's binary format isn't human-readable in a browser network tab the way JSON is, and it doesn't get HTTP caching for free the way a GET to a stable REST URL does, since there's no natural per-action URL to cache against. It also generally requires generated client/server code from a shared schema (a .proto file) rather than being callable from any HTTP client with no special tooling — a real onboarding and tooling cost that plain REST-over-JSON doesn't have.

The practical split: internal vs. external APIs

This is where the decision usually actually lands: internal, service-to-service calls (inside a microservices architecture, where both ends are controlled by the same organization and performance compounds across many hops) commonly favor RPC/gRPC for its speed and generated-client convenience. External, public-facing APIs (used by third parties, browsers, or anyone outside the organization) commonly favor REST specifically because it's universally callable from any HTTP client with no special tooling, human-readable for debugging, and gets HTTP caching for free.

Why this matters in an interview

Naming this internal-vs-external split explicitly — rather than treating REST and RPC as competing for the same use case — shows the tradeoff is genuinely understood: gRPC's performance advantages matter most exactly where REST's universal-client advantage matters least (internal calls, controlled clients), and vice versa for public APIs.

REST vs. RPC (gRPC): pros and cons

REST

  • Callable from any HTTP client with no special tooling or generated code
  • Human-readable JSON, easy to inspect and debug in a browser or with curl
  • Gets HTTP-native caching for free via stable, resource-oriented URLs

RPC (gRPC)

  • Binary payloads aren't human-readable without dedicated tooling
  • Requires generated client/server code from a shared schema file
  • No natural per-action URL to hang standard HTTP caching off of

Further Reading

Saved locally in your browser — visible in the sidebar as you go.