Handbooks  /  gRPC vs REST
Engineering~8 min readComparison
Head to Head

gRPC vs REST: reach or speed?

gRPCvsREST

Both are ways for services to talk over the network, and the honest answer is you often want both — in different places. REST over HTTP and JSON is universal: every language, browser, proxy and curl understands it, which makes it the right skin for public APIs. gRPC uses typed protobuf over HTTP/2: compact, fast, streaming, code-generated — the right plumbing between your own services.

01

The core difference: audience

REST models resources over plain HTTP with human-readable JSON. Its superpower is universality — nothing to install, cacheable by any proxy, debuggable with a browser or curl, understood everywhere. gRPC takes a contract-first approach: you define messages and services in a protobuf file and generate typed clients/servers in every language, sending compact binary over HTTP/2 with multiplexed streams and native streaming. Its superpower is efficiency and type safety between machines.

→ The rule

Exposing an API to the public, browsers, or partners? REST — universal tooling and debuggability win. High-volume, low-latency service-to-service traffic among your own polyglot services? gRPC — typed contracts, streaming, and smaller/faster payloads win.

02

Head to head

DimensiongRPCREST
PayloadProtobuf (compact binary)JSON (human-readable text)
TransportHTTP/2 (multiplexed, streaming)HTTP/1.1 or /2, request/response
ContractStrongly typed .proto, codegenConvention + OpenAPI (optional)
StreamingNative (uni + bidirectional)Awkward (SSE, polling, websockets)
Browser supportNeeds a proxy (gRPC-Web)Native everywhere
DebuggabilityNeeds tooling (binary)curl, browser, any HTTP tool
CachingNot by standard HTTP cachesCacheable by any proxy/CDN
Best fitInternal microservices, low latencyPublic APIs, browser/partner clients
03

When to use each — and both

Reach for gRPC

  • Chatty internal service-to-service calls
  • Polyglot teams wanting generated, typed clients
  • Low latency / high throughput matters
  • Streaming (real-time feeds, large transfers)
  • Strict, versioned contracts (protobuf evolution)

Reach for REST

  • Public or partner-facing APIs
  • Browser clients (no proxy needed)
  • You want curl-level debuggability
  • HTTP caching / CDN benefits
  • Broad, zero-friction adoption
→ The pattern that ships

REST at the edge, gRPC inside. Expose a public REST/JSON API for the world, and use gRPC for the fast, typed traffic between your own services behind it — often with an API gateway translating between them. You’re not choosing one forever; you’re placing each where its strength fits. See the API Design handbook for the full picture.

04

Why protobuf + HTTP/2 actually saves bytes and round-trips

The speed gap isn't marketing — it comes from two concrete mechanical differences. First, payload encoding: JSON repeats every field name as a string in every message ({"user_id": 42, "user_name": "..."}), while protobuf encodes each field as a small numeric tag defined once in the .proto schema — the wire format never re-sends "user_id" as text, just a tag byte and the value. For small messages the difference is modest; for high-volume internal traffic (millions of calls between services) it adds up to meaningfully less bandwidth and, just as importantly, less CPU spent parsing text into structured data on both ends.

Second, transport: REST over HTTP/1.1 opens one request per connection at a time (or relies on connection pooling to fake concurrency), while gRPC's HTTP/2 foundation multiplexes many concurrent calls over a single TCP connection — no head-of-line blocking between unrelated requests, no repeated TLS handshake overhead per call. Combined with native bidirectional streaming (a single call that sends and receives a continuous sequence of messages, not just one request and one response), this is what makes gRPC a genuinely different tool for chatty internal traffic — many small, frequent calls between services — rather than just "REST but smaller."

→ The trade you're actually making

Protobuf's compact tags require the schema to decode — you can't read a gRPC payload with your eyes the way you can curl a REST endpoint and see JSON. Efficiency on the wire trades away the "just look at it" debuggability that makes REST so approachable.

05

A worked scenario: a ride-hailing driver-location feed

Say a ride-hailing app needs to stream a driver's GPS position to the rider's app every second while a trip is active — and separately, expose a public API partners can query for trip receipts. These are genuinely different problems, and the comparison table above explains why they get different tools.

The driver-location stream is exactly gRPC's native case: a server-streaming RPC where the driver's phone opens one call and the server pushes a continuous sequence of position updates over it, multiplexed alongside dozens of other gRPC calls that phone might be making (trip status, chat messages) on the same HTTP/2 connection. Modeling this in REST would mean either polling ("GET /driver/location every second," wasteful and laggy) or reaching for Server-Sent Events or WebSockets — workable, but bolted onto HTTP rather than native to the protocol the way gRPC's streaming is.

The trip-receipt API for partners is exactly REST's native case: a partner's backend (maybe written in a language with no gRPC tooling investment, maybe just curling it from a script during integration testing) wants GET /v1/trips/{id}/receipt returning JSON it can read directly, cache at a CDN edge if it's immutable, and debug by pasting the URL into a browser. Forcing this through gRPC would mean every partner needs a gRPC-Web proxy and generated client code just to fetch a receipt — friction with no payoff, since receipt-fetching isn't high-frequency or latency-sensitive the way the location stream is.

→ The pattern generalizes

The decision isn't "which protocol is better" — it's "who's the caller, and how often do they call." High-frequency, low-latency, internal-or-controlled callers favor gRPC. Low-frequency, must-be-universally-reachable, externally-debugged callers favor REST. Most real systems have both kinds of caller and use both protocols.

06

Common mistakes

MistakeWhy it bites
Exposing gRPC directly to a public/partner audienceEvery partner now needs gRPC tooling and codegen in their language before they can make a single call, and browsers can't speak raw gRPC at all without a gRPC-Web proxy — a huge adoption tax compared to "curl this URL."
Treating protobuf schema changes casuallyProtobuf's wire format depends on field numbers staying stable — reusing a field number for a different field, or changing a field's type, silently corrupts data for any client still running the old schema. REST/JSON is more forgiving of ad-hoc field additions because field names, not positional numbers, carry the meaning.
Building bidirectional streaming on top of REST pollingRepeated polling for "has anything changed" wastes requests on the common case of "no" and adds latency up to the polling interval before a real change is seen — the exact problem gRPC's native streaming (or WebSockets) exists to avoid.
Assuming gRPC is always faster in practiceFor small payloads over a fast local network, HTTP/1.1 REST overhead can be negligible, and the added complexity of protobuf schemas, codegen tooling, and gRPC-Web proxying may cost more in engineering time than it saves in milliseconds — measure before assuming.
Your call

Which would you pick?

Three situations. Pick the side you'd actually build — the explanation follows.

A partner-facing API that outside companies will integrate with, in languages you do not control.

Two internal services exchange millions of small messages per minute inside your own network, both owned by your team.

A protobuf field is no longer used, so a developer reuses its field number for a new field of a different type.

Frequently asked

Quick answers

What is the difference between gRPC and REST?

REST sends human-readable JSON over standard HTTP and is universal, cacheable and debuggable — ideal for public APIs. gRPC sends compact binary protobuf over HTTP/2 with typed, generated clients and native streaming — ideal for fast internal service-to-service calls. REST optimizes for reach; gRPC for efficiency and type safety.

Is gRPC faster than REST?

Generally yes for service-to-service traffic: protobuf payloads are smaller than JSON, HTTP/2 multiplexes many calls over one connection, and there is no text parsing overhead. But the gain matters most at high volume and low latency; for a public API, REST’s universality usually outweighs raw speed.

Can I use gRPC in the browser?

Not directly — browsers can’t speak raw gRPC, so you need a proxy layer like gRPC-Web or a REST/JSON gateway. This is a big reason REST remains the default for public and browser-facing APIs, while gRPC shines between backend services.

Should I use gRPC or REST?

Use REST at the edge for public, browser and partner APIs where universality and debuggability win. Use gRPC inside for chatty, low-latency, polyglot service-to-service traffic where typed contracts and streaming win. Many systems use both, with a gateway translating between them.

▶  Watch it explained

gRPC vs REST: spell it out, or agree on a phrasebook first

gRPC vs REST · Engineering · Vibe Engines · 2026
Finished this one? 0 / 208 Handbooks done

Explore the topic

See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.

More Handbooks