gRPC fits service-to-service traffic where contracts and streaming matter. REST fits any surface a third party will touch: browsers, mobile apps, partner integrations. Most teams end up with both, gRPC internally and REST at the edge.
gRPC
High-performance RPC framework over HTTP/2 with Protocol Buffers.
gRPC and REST are not the same kind of choice. gRPC is a framework with strong opinions about transport, encoding, and schemas. REST is an architectural style with weak conventions and broad reach. The split most teams arrive at is gRPC behind the load balancer, REST or GraphQL in front of it.
Quick takes
If you're…
You are building service-to-service APIs inside your own cluster→gRPCSmaller payloads, faster serialization, streaming, and schema contracts. The wins compound at scale.
You are exposing an API directly to web browsers→RESTgRPC needs grpc-web with a proxy in front. REST works natively in fetch.
You are publishing an API for third-party developers→RESTREST has near-zero onboarding cost. Every language parses JSON; every tool understands HTTP.
You need bidirectional streaming (chat, telemetry, gaming)→gRPCgRPC streams are built in. REST needs SSE or WebSocket workarounds.
You are modelling resources (users, orders, posts) with CRUD→RESTREST’s resource orientation is a natural fit. gRPC RPCs feel forced for this shape.
You need browser caching, CDN caching, and HTTP semantics→RESTREST inherits decades of HTTP infrastructure. gRPC over CDNs is awkward.
You want strict contracts checked at compile time→gRPCprotoc generates type-safe clients in many languages. OpenAPI exists for REST but enforcement is looser.
You want a wire format smaller and faster to parse than JSON→gRPCProtobuf is binary and schema-aware. JSON is text and schema-less on the wire.
HTTP/2 (multiplexed streams, header compression) with Protocol Buffers (binary, schema-aware). Smaller payloads, faster parsing. HTTP/3 over QUIC is shipping in current libraries.
REST
HTTP/1.1 or HTTP/2 with JSON (text, schema-less on the wire). Universally readable. Larger over the wire and slower to serialize at high QPS.
core
Contracts and codegen
edge: gRPC
gRPC
.proto files generate strongly-typed clients and servers in many languages. Schemas are enforced at compile time. Versioning uses field numbers and reserved tags.
REST
OpenAPI or Swagger provides a spec, but enforcement is opt-in and tends to drift. Hand-written client libraries are common. Documentation-driven more than codegen-driven.
features
Streaming
edge: gRPC
gRPC
Four call shapes: unary, server-streaming, client-streaming, bidirectional-streaming. All built on HTTP/2 streams. Production-grade for chat, telemetry, and file transfer.
REST
Server-Sent Events (one-way), WebSockets (separate protocol), HTTP long-poll. Each has its own quirks. No unified streaming story.
ops
Browser support
edge: REST
gRPC
Not supported directly. grpc-web with a proxy (Envoy or gRPC-Web Gateway) translates between browser-friendly text and gRPC. One more hop, one more piece to operate.
REST
Native in every browser. fetch is built in. Works through corporate proxies, CDNs, and browser extensions.
ops
Tooling and debugging
edge: REST
gRPC
grpcurl, BloomRPC, Postman’s gRPC mode, evans. Improving steadily. Server reflection helps. Most engineers still reach for grpcurl at the terminal.
REST
curl, Postman, browser devtools, every HTTP proxy, every API testing tool that has ever shipped. The breadth of tooling is REST’s most underrated advantage.
features
HTTP caching
edge: REST
gRPC
No native HTTP cache semantics. Cache-Control, ETag, and If-None-Match do not apply. Caching has to be built into the application layer.
REST
Full HTTP cache semantics. CDNs work. Browsers cache. Conditional requests save bandwidth. A large operational lever.
features
Error handling
edge: gRPC
gRPC
About 17 standard gRPC status codes. Trailers carry rich error details through google.rpc.Status. Cleaner than reusing HTTP status codes.
REST
HTTP status codes (5xx for server, 4xx for client) plus an error body convention (commonly JSON {error: ...}). Universally understood; semantically muddier.
ecosystem
Adoption and developer mindshare
tie
gRPC
Dominant inside Google, Netflix, Square, Lyft, and Cloudflare’s internals. Service-mesh-native; Istio and Linkerd assume gRPC works. Less common in startups and public APIs.
REST
Dominant everywhere else. Every SaaS API, every mobile SDK, every webhook, every partner integration. The default mental model when someone says "an API."
Benchmark
Round-trip latency, 10KB payload, same datacenter
Go client and server, 8-core m5.2xlarge instances in the same AZ, 100 concurrent requests. JSON over HTTP/1.1 for REST, Protobuf over HTTP/2 for gRPC. Numbers from the official grpc.io Go benchmarks dashboard; payload sizes verified against Google's Protobuf-vs-JSON wire-format reference.
Frontend teams want to pick exactly the fields they need
JSON-RPC
REST’s simplicity with an RPC mental model
Cap'n Proto
gRPC-shaped, with zero-copy and capability-based security
Apache Avro with Kafka
Schema evolution and event streaming together
HTTP/2 with JSON (no framework)
Streaming plus cache plus REST tooling
WebSockets
Bidirectional, low-latency, browser-first
Situational picks
For specific cases.
Public API for third-party developers
REST
Near-zero onboarding cost. Every language and every tool already understands it. Pair with an OpenAPI spec.
Internal microservices in Kubernetes with a service mesh
gRPC
mTLS, load balancing, and retries are all assumed-gRPC by Istio and Linkerd. Faster wire and a cleaner contract.
Mobile app talking to a backend
REST
Mobile networks are flaky. HTTP semantics (cache, redirects, conditional requests) save battery and bandwidth. Mobile gRPC libraries work, but the operational story is harder.
Real-time multiplayer, streaming telemetry, or chat backbone
gRPC
Bidirectional streaming is what gRPC was designed for. WebSocket works, but the rest of the framework is yours to build.
Small startup building a SaaS without performance bottlenecks yet
REST
REST and JSON gets a product to market faster. Migrate hot paths to gRPC later if measurement shows they need it.
You want fewer paradigms in the codebase
GraphQL
One schema, one endpoint, both internal and public consumers fetch what they need. Higher upfront cost, lower ongoing API-surface cost.