Skip to main content

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.

FeatureRESTgRPC
ProtocolHTTP/1.1 or HTTP/2, any transportHTTP/2 mandatory
SerializationJSON (text) – human-readable, ~3–10x larger than ProtobufProtocol Buffers (binary) – compact, schema-enforced
SchemaOptional (OpenAPI/Swagger) – not enforced by defaultMandatory .proto files – enforced at compile time
Type safetyRuntime only – type mismatches discovered at runtimeCompile-time – generated stubs enforce types
StreamingOne request, one response (SSE/WebSocket for streaming)Native: unary, server streaming, client streaming, bidirectional
Browser supportNative – works in any browser with fetch/XHRNot native – requires gRPC-Web proxy (Envoy) or gRPC-Web library
Human readabilityHigh – JSON is readable in curl, browser dev toolsLow – binary encoding requires special tooling (grpcurl, Evans)
Code generationOptional (OpenAPI generators)Required – stubs generated from .proto for each language
PerformanceBaseline – JSON parsing overhead, text encoding5–10x smaller payloads, faster serialization
Error modelHTTP status codes (200, 400, 404, 500)gRPC status codes (OK, INVALID_ARGUMENT, NOT_FOUND, INTERNAL)
VersioningURL-based (/v1/, /v2/) or header-basedField 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.