REST vs gRPC
REST (REpresentational State Transfer) is an architectural style, not a protocol – it uses HTTP methods (GET, POST, PUT, DELETE) with JSON bodies over HTTP/1.1 or HTTP/2. gRPC (Google Remote Procedure Call) is a protocol – it uses HTTP/2 with Protocol Buffer serialization, code-generated stubs, and a strict schema defined in .proto files. The choice affects developer experience, network efficiency, browser compatibility, and operational tooling.
REST uses HTTP/1.1 or HTTP/2 with JSON over text – human-readable, universally supported, and browser-friendly. gRPC uses HTTP/2 with Protocol Buffers (binary) – strongly typed, 5–10x smaller payloads, and bidirectional streaming. REST is the right default for public APIs and browser clients. gRPC is the right choice for internal microservice communication where performance and schema enforcement matter.
| Feature | REST | gRPC |
|---|---|---|
| Protocol | HTTP/1.1 or HTTP/2, any transport | HTTP/2 mandatory |
| Serialization | JSON (text) – human-readable, ~3–10x larger than Protobuf | Protocol Buffers (binary) – compact, schema-enforced |
| Schema | Optional (OpenAPI/Swagger) – not enforced by default | Mandatory .proto files – enforced at compile time |
| Type safety | Runtime only – type mismatches discovered at runtime | Compile-time – generated stubs enforce types |
| Streaming | One request, one response (SSE/WebSocket for streaming) | Native: unary, server streaming, client streaming, bidirectional |
| Browser support | Native – works in any browser with fetch/XHR | Not native – requires gRPC-Web proxy (Envoy) or gRPC-Web library |
| Human readability | High – JSON is readable in curl, browser dev tools | Low – binary encoding requires special tooling (grpcurl, Evans) |
| Code generation | Optional (OpenAPI generators) | Required – stubs generated from .proto for each language |
| Performance | Baseline – JSON parsing overhead, text encoding | 5–10x smaller payloads, faster serialization |
| Error model | HTTP status codes (200, 400, 404, 500) | gRPC status codes (OK, INVALID_ARGUMENT, NOT_FOUND, INTERNAL) |
| Versioning | URL-based (/v1/, /v2/) or header-based | Field numbers in .proto – backward-compatible by convention |
When to use REST
REST is the right choice for: public APIs consumed by third parties, browser-based frontends (native fetch support), mobile apps where JSON tooling is mature, simple CRUD services, and any context where human readability and universal client support matters more than performance. Most public APIs (Stripe, Twilio, GitHub) use REST.
When to use gRPC
gRPC is the right choice for: internal microservice-to-microservice communication, high-throughput services where serialization overhead is measurable, real-time bidirectional streaming (live updates, chat, telemetry), polyglot service meshes where strongly-typed contracts prevent integration bugs, and services in Kubernetes where gRPC load balancing is configured at the proxy layer.
Common Mistakes
- Using gRPC for a public API – browser support requires grpc-web and an Envoy proxy, making the client story significantly more complex than REST. Public APIs should almost always be REST.
- Using REST for internal microservices with many endpoints – JSON parsing at 10,000 RPS adds measurable latency. gRPC's binary encoding and HTTP/2 multiplexing can cut latency significantly at scale.
- Not versioning .proto files – Protocol Buffer field numbers are the versioning mechanism. Changing field numbers is a breaking change. Adding new fields (with new numbers) is backward-compatible.
- Using gRPC without a service mesh – gRPC requires HTTP/2 load balancing at the connection level (unlike HTTP/1.1 round-robin at the connection level). Without Envoy/Linkerd/Istio, gRPC load balancing in Kubernetes is broken (all traffic goes to one pod per connection).
- Assuming gRPC works in all environments – some corporate firewalls and API gateways don't support HTTP/2 trailers, which gRPC uses for status codes. Test your infrastructure before committing to gRPC.
FAQ
Can I use both REST and gRPC in the same service?
Yes. gRPC-Gateway (grpc-ecosystem/grpc-gateway) generates a reverse-proxy that translates REST/JSON to gRPC/Protobuf automatically from annotations in .proto files. This is a common pattern: expose REST for external consumers and gRPC for internal services, using a single proto definition as the source of truth.
Is gRPC faster than REST in every case?
Not for all payloads. For small payloads (<1KB), the difference is negligible. gRPC's advantage is most pronounced for large payloads (Protobuf's binary encoding vs JSON's text overhead), high-frequency calls (HTTP/2 multiplexing amortizes connection overhead), and streaming scenarios. For a simple health check endpoint, REST and gRPC performance is indistinguishable.
What replaced gRPC in some organizations?
For browser-facing APIs, many teams have moved to GraphQL (flexible queries, single endpoint) or tRPC (TypeScript type-safe RPC over HTTP). For internal services, some teams use Connect Protocol (connectrpc.com) – a gRPC-compatible protocol that works over HTTP/1.1 and is browser-native without a proxy.