API design
REST vs gRPC
Short answer
Use REST for public APIs, browser clients, and integrations where HTTP tooling and debuggability win. Use gRPC for controlled service-to-service calls when generated types, multiplexed HTTP/2, streaming, and a strict schema justify the protobuf toolchain; do not select it merely because a benchmark shows lower overhead.
Written and reviewed by Sahil Srivastav
What each one actually is
REST models resources and operations over HTTP semantics, commonly using JSON and status codes. Its strength is reach: browsers, curl, proxies, documentation tools, and third-party clients already understand the transport.
gRPC defines methods in protobuf, generates clients and servers, and normally uses HTTP/2. Unary calls resemble request/response APIs, while server, client, and bidirectional streaming are part of the contract.
Both can be reliable APIs. Retries, deadlines, authentication, compatibility, and observability still require deliberate policy around either transport.
Side by side
| REST | gRPC | |
|---|---|---|
| Client reach | Excellent for browsers and external consumers | Best with generated clients; browser use needs gRPC-Web or a gateway |
| Contract | OpenAPI can describe it, but discipline varies | Protobuf contract drives generated code and compatibility checks |
| Payload | Usually human-readable JSON | Compact binary protobuf by default |
| Streaming | Possible with SSE, chunking, or WebSockets | Unary and all streaming modes are built into the model |
| Debugging | curl and browser tools work immediately | Needs grpcurl, reflection, and protobuf-aware tooling |
| Evolution | Additive JSON fields are easy; semantics need discipline | Field numbering and protobuf compatibility rules are explicit |
| Proxy compatibility | Broad HTTP infrastructure support | HTTP/2, load balancers, and timeouts need verification |
| Failure semantics | HTTP status and body conventions | gRPC status codes, trailers, deadlines, and cancellation |
Choose REST when
- Customers, partners, or browser JavaScript call the API
- The endpoint must be easy to inspect with ordinary HTTP tooling
- Caching, hyperlinks, or standard HTTP semantics are part of the interface
- The organisation cannot require generated client tooling
Choose gRPC when
- Many internal services share a versioned contract
- High call volume benefits from compact payloads and multiplexed connections
- Streaming or cancellation is central to the interaction
- You control both ends and can operate protobuf, reflection, and gateway tooling
The trade-off in detail
gRPC’s generated code prevents a class of drift but can make a small change feel like a release across many repositories. Pin and test generated artefacts, and use compatibility checks before publishing a .proto change.
HTTP/2 does not remove queueing or timeout problems. A single connection can carry many calls, but a bad deadline policy still ties up server work and can cause retries to multiply. Propagate deadlines and cancel downstream work.
REST’s apparent simplicity can hide an undocumented contract in status codes and error JSON. Write an error schema and compatibility rules; “just JSON” is not a substitute for an API design.
Things that are commonly said and are wrong
- “gRPC is always faster.” It often reduces encoding overhead, but network distance, server work, connection setup, and retries dominate many calls.
- “REST cannot stream.” SSE, chunked responses, and WebSockets provide streaming patterns, with different intermediaries and semantics.
- “HTTP/2 makes gRPC safe to retry.” A transport retry can duplicate a non-idempotent method; define idempotency explicitly.
FAQ
Which should a public API use?
REST is usually the safer default because clients, browsers, gateways, and documentation tools support it directly. A public gRPC API can work, but you must provide client libraries and address browser and proxy constraints.
Can a system expose both?
Yes. A gRPC internal service can sit behind a REST or JSON transcoding gateway. Keep the external contract deliberate; exposing an internal protobuf model unchanged often leaks implementation details.
What is the biggest gRPC production failure mode?
Unbounded or missing deadlines. Calls remain in flight while an upstream request has already timed out, consuming threads and connections. Set a deadline at the edge and propagate the remaining budget downstream.