API protocol comparison
gRPC vs REST
REST is the default choice for most web APIs. gRPC is the choice when performance, streaming, and contract-first design matter more than broad compatibility. Understanding when to use each — and the vocabulary around both — is essential for backend and platform engineers.
TL;DR
- REST — JSON over HTTP/1.1 or HTTP/2. Text-based, human-readable, cacheable, universally supported by browsers and HTTP clients. The default for public APIs.
- gRPC — Protocol Buffers binary over HTTP/2. Typed schema (.proto file), fast serialisation, streaming support, generated client/server code. The default for high-performance internal microservice communication.
- A common pattern is gRPC between internal services and REST (or GraphQL) for the public-facing API — best of both worlds.
Side-by-side comparison
| Aspect | REST | gRPC |
|---|---|---|
| Serialisation | JSON (text) — human-readable, larger, slower | Protocol Buffers (binary) — compact, fast, not human-readable |
| Schema / typing | Optional (OpenAPI) — JSON is loosely typed | Mandatory — .proto file defines all types strictly |
| Transport | HTTP/1.1 or HTTP/2 | HTTP/2 required |
| Streaming | Limited — SSE for server stream; WebSocket for bidirectional | Native — unary, server stream, client stream, bidirectional |
| Browser support | Full — fetch/XHR work natively | No native browser support; requires gRPC-Web proxy |
| Code generation | Optional (OpenAPI codegen) | Required and central — protoc generates typed stubs |
| Learning curve | Low — HTTP knowledge sufficient | Higher — protobuf IDL, generated code, HTTP/2 concepts |
| Caching | HTTP caching works natively | No standard HTTP caching for binary payloads |
| Debugging | Easy — curl, Postman, browser devtools | Harder — binary format requires grpcurl or protobuf-aware tools |
| Best for | Public APIs, browser clients, partner integrations | Internal microservices, real-time streaming, high-throughput RPC |
When to use REST
- Public-facing API. Third-party developers, browser clients, and partner integrations expect REST. JSON is universally understood; curl and Postman are zero-setup debugging tools.
- HTTP caching matters. CDN caching, ETag, and Cache-Control headers work natively with REST. gRPC's binary POST requests are not cacheable by standard CDNs.
- Team is not ready for the protobuf toolchain. REST has a lower operational overhead — no .proto compilation step, no generated stubs to maintain.
When to use gRPC
- Internal microservice communication. Services that call each other hundreds of times per second benefit from gRPC's binary encoding and HTTP/2 multiplexing.
- Streaming use cases. Real-time updates, server push, and bidirectional data flows are first-class in gRPC. Doing the same in REST requires WebSockets or SSE bolted on.
- Strict, contract-first API design. The .proto file is the single source of truth, and generated stubs guarantee that clients and servers stay in sync.
- Polyglot microservices. Generated clients in Go, Java, Python, and TypeScript all share the same .proto contract — no hand-rolled HTTP clients with drifting type definitions.
English phrases engineers use
gRPC conversations
- "We use gRPC for inter-service communication — REST for the public API."
- "The proto file defines the contract — both teams work from it."
- "We're using gRPC streaming for real-time updates to the dashboard."
- "Run protoc to regenerate the stubs after changing the schema."
- "Use grpcurl to test the endpoint — it's like curl for gRPC."
REST conversations
- "REST for the public API, gRPC internally — best of both worlds."
- "The response is too large — we should paginate or move to GraphQL."
- "All public endpoints are documented in OpenAPI — clients can generate SDKs."
- "The CDN is caching GET responses — cuts our origin load by 60%."
- "We use JSON:API format for consistent response structure."
Key vocabulary
- Protocol Buffers (protobuf) — Google's binary serialisation format; more compact and faster than JSON, but not human-readable.
- .proto file — the schema file that defines gRPC services, methods, and message types in the protobuf IDL.
- Stub — auto-generated client/server code produced by the protoc compiler from a .proto file.
- Unary RPC — the simplest gRPC pattern: one request, one response (analogous to a REST call).
- Bidirectional streaming — a gRPC pattern where both client and server send a stream of messages concurrently over a single connection.
- gRPC-Web — a protocol adaption that allows browser JavaScript to call gRPC services via an HTTP/1.1-compatible proxy.
- IDL (Interface Definition Language) — a language for describing an API's interface in a language-neutral way; protobuf is gRPC's IDL.
Quick decision tree
- Public API consumed by external developers → REST
- Internal service-to-service calls at high throughput → gRPC
- Real-time bidirectional streaming → gRPC
- Browser client consuming the API directly → REST
- Polyglot microservices that need a shared contract → gRPC
- Need CDN caching → REST
- Both public and internal API needed → REST externally + gRPC internally
Frequently asked questions
Is gRPC faster than REST?
Usually yes, significantly so for high-throughput internal service communication. Protocol Buffers binary serialisation is 5–10x smaller and faster to encode/decode than JSON. HTTP/2 multiplexing eliminates head-of-line blocking and reduces connection overhead. In benchmarks, gRPC typically outperforms REST by 25–50% on latency and can be dramatically faster on CPU-bound serialisation at scale. The gap is most visible in inter-service calls with small, frequent payloads.
What is a .proto file?
A .proto file is the schema definition for a gRPC service, written in Protocol Buffers (protobuf) IDL. It defines the service name, the RPC methods (with request and response types), and the message structures (field names, types, and field numbers). The protoc compiler reads the .proto file and generates strongly typed client and server code in your target language (Go, Java, Python, TypeScript, etc.). The .proto file is the contract shared between services.
Can browsers use gRPC natively?
No, not directly. Standard gRPC requires HTTP/2 at the transport level, and browsers cannot control HTTP/2 framing — they use the Fetch API which abstracts the transport. gRPC-Web is a specification that adapts gRPC for browser clients via a proxy (Envoy) that translates between gRPC-Web and standard gRPC. Alternatively, Connect (from Buf) is a modern protocol compatible with both gRPC and standard browsers over HTTP/1.1 or HTTP/2.
What types of streaming does gRPC support?
gRPC supports four communication patterns: unary (one request, one response — like REST), server streaming (one request, stream of responses — like server-sent events), client streaming (stream of requests, one response), and bidirectional streaming (both sides stream concurrently). REST over HTTP/1.1 supports only unary calls; server-sent events add one-way server streaming. Bidirectional streaming requires WebSockets in REST-based systems.
How do you version a gRPC API?
Protocol Buffers use field numbers to identify fields, not names — so you can add new fields without breaking existing clients (they simply ignore unknown fields). Removing or changing the type of an existing field number is a breaking change. Common versioning strategies include: using package versioning in the .proto (package myservice.v1), maintaining backward-compatible field additions, and using a separate .proto file/package for major breaking changes.
When would you use REST instead of gRPC?
Use REST when you need broad client compatibility (public APIs, browser clients, third-party integrations), when human readability of the wire format matters (JSON is debuggable with curl), when your team is not ready to adopt the protobuf toolchain, or when HTTP caching at a CDN is important. gRPC's binary format and strict tooling requirements make it less suitable for public APIs where you do not control the client.