Skip to content

gRPC vs REST

REST and gRPC solve the same broad problem — one program talking to another — but they frame it differently.

  • REST thinks in resources. You have nouns (/users/42), and you act on them with a small fixed set of verbs (GET, POST, PUT, DELETE). The data is usually JSON, and the contract is often a document (OpenAPI) or just convention.
  • gRPC thinks in procedures. You have methods (GetUser, CreateOrder, StreamPrices), each with a typed request and response defined in a .proto. The data is binary protobuf, and the contract is the schema itself.

Neither model is “correct” — they optimize for different things.

REST + JSONgRPC + Protobuf
PayloadText (JSON) — human-readable, largerBinary — compact, fast to parse
ContractOptional (OpenAPI / convention)Mandatory (.proto), enforced by codegen
Browser supportNative, universalNeeds gRPC-Web + a proxy
StreamingAwkward (SSE, long-poll)First-class, bidirectional
Human debuggabilitycurl and read itNeeds tooling (grpcurl, reflection)
Codegen / type safetyAdd-on, variesBuilt in, across 11+ languages
Best fitPublic APIs, browsers, simple CRUDInternal service-to-service, low latency, streaming

Two things make gRPC efficient on the wire:

flowchart TB
  subgraph rest["REST + JSON"]
    r1["parse text JSON
(reflective, larger)"] --> r2["new connection
or HTTP/1.1 head-of-line"]
  end
  subgraph grpc["gRPC + Protobuf"]
    g1["decode binary protobuf
(schema-driven, compact)"] --> g2["HTTP/2 multiplexing
many calls, one connection"]
  end
Where gRPC saves time versus REST/JSON
  1. Protobuf is smaller and cheaper to decode than JSON. Fields are tagged by number, not by name, and values are packed as binary. There is no reflective key-matching and no text parsing.
  2. HTTP/2 multiplexing lets many in-flight calls share one connection without blocking each other (the next lesson goes deep on this).

But be honest about scale: for a request every few seconds, this difference is invisible. It matters when you make thousands of calls per second between services, or move large/streaming payloads.

gRPC is a great default for internal microservices, but it is the wrong tool when:

  • The client is a browser and you can’t run a proxy. Browsers can’t speak raw gRPC; you need gRPC-Web plus a translating proxy (Envoy or the built-in one). For a simple public web API, REST is less friction.
  • You want a public, third-party-friendly API. Most external developers expect curl, JSON, and an OpenAPI page. gRPC raises the barrier to entry.
  • The API is trivial CRUD with low traffic. The .proto toolchain and binary debugging are overhead you won’t recoup.
  • Human-readable traffic is a hard requirement (some compliance or debugging setups). Binary frames need extra tooling to inspect.
What is the core framing difference between REST and gRPC?
Which is a genuine reason to prefer REST over gRPC?
Why is protobuf typically faster to process than JSON?
What extra piece does a browser need to talk to a gRPC service?