gRPC vs REST vs GraphQL
Fast recall
Quick revision
Core answer
Cache-Control works for REST, not GraphQL).Whether you can match workload shape (public vs internal, nested reads vs RPC-style writes, streaming vs request-response) to the protocol, and understand the operational cost of each — caching, rate-limiting, schema governance, client tooling.
Picking one for all APIs (usually REST for everything, or GraphQL for everything) instead of blending — e.g. gRPC between internal services, REST for public APIs, GraphQL for mobile/BFF. Or comparing them on latency benchmarks alone and ignoring developer ergonomics and ecosystem.
Discuss gRPC-Web for browsers, GraphQL federation vs REST BFFs, persisted queries and automatic persisted queries (APQ), gRPC deadlines vs HTTP timeouts, and how HTTP/3 narrows the protocol gap.
Interview-ready guide
Interview answer
gRPC, REST, and GraphQL are not competing technologies — they solve different coupling problems, and the right choice depends on who is calling, at what frequency, and whether the caller is internal or external.
gRPC — internal high-RPS paths:
- My default for internal service-to-service calls where performance matters: Protobuf payloads are 5–10× smaller than JSON, and HTTP/2 multiplexing means multiple RPCs share one TCP connection, eliminating the per-request TLS handshake cost
- Strict schema contracts via
.protofiles catch breaking changes at compile time — a renamed field that would silently break REST consumers at runtime produces a build error with generated stubs - The constraint: gRPC requires a grpc-web proxy for browser clients; HTTP/2 trailers are not accessible from browser JavaScript, so anything external-facing needs REST at the edge
REST — external-facing, universal:
- My default for anything external-facing: every developer knows how to call a REST API with curl, CDN caching works natively, and API management tooling assumes HTTP/JSON
- Requiring external partners to install protobuf compilers eliminates any performance advantage; REST's universality is the advantage
- For internal calls at moderate frequencies, REST is still fine because debugging simplicity outweighs microsecond differences
GraphQL — complex frontend aggregation:
- Fills the niche where frontend screens need data from multiple backend domains with varying field requirements
- The catch: without depth limiting and query cost analysis, one deeply nested query can generate hundreds of database calls; use persisted queries in production to control the query surface
The architectural combination:
- The strongest production architectures combine all three: gRPC inside the mesh for throughput, REST at the edge for universal compatibility, GraphQL for complex frontend aggregation behind a BFF layer
I recommend gRPC when the caller is a service you control and call frequency is high, REST for external callers, and GraphQL when frontends need flexible data shapes from multiple domains.
gRPC vs REST vs GraphQL
Direct Answer
gRPC wins for internal service-to-service: HTTP/2, Protocol Buffers, strong types, built-in deadlines and streaming — pick it when both sides are your own code. REST wins for public APIs: universal clients, CDN-cacheable reads, simple debugging with curl, great for CRUD over JSON. GraphQL wins for client-shaped reads: mobile and web UIs that need nested data in one round-trip, multiple clients with different data needs, schema-as-contract. Most real systems blend them — gRPC between services, REST for the public API, GraphQL as a BFF for rich UIs. Decide on workload shape (nested reads vs RPC writes vs streaming), audience (internal vs public), and caching needs (Cache-Control works for REST, not GraphQL).
Code Example
// Same "get user with last 5 orders" request, three ways.
// ==== REST (fetch, JSON) =================================================
const user = await fetch(`/v1/users/${id}`).then(r => r.json());
const orders = await fetch(`/v1/users/${id}/orders?limit=5`).then(r => r.json());
const items = await Promise.all(
orders.map((o: any) => fetch(`/v1/orders/${o.id}/items`).then(r => r.json()))
);
// ~3 + N round-trips, client stitches.
// ==== GraphQL (fetch, one query) =========================================
const gql = `query($id: ID!) {
user(id: $id) {
id displayName
orders(last: 5) {
id total { amount currency }
items { quantity product { sku name thumbnailUrl } }
}
}
}`;
const { data } = await fetch('/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query: gql, variables: { id } }),
}).then(r => r.json());
// 1 round-trip, shape matches UI.
// ==== gRPC (via gRPC-Web proxy for browsers) =============================
import { UserServiceClient } from './generated/user_service_grpc_web_pb';
const client = new UserServiceClient('https://api.example.com', null, null);
const req = new GetUserWithOrdersRequest();
req.setUserId(id); req.setLast(5);
const res = await new Promise((ok, fail) =>
client.getUserWithOrders(req, {}, (err, resp) => err ? fail(err) : ok(resp)));
// Strong types on the client, binary protobuf on the wire, but:
// - Needs generated code (build step)
// - Needs gRPC-Web proxy (Envoy) for browsers
// - No CDN caching of responses
// Best for service-to-service, not typically for browser clients.
Common Mistakes & Pitfalls
Picking one for all APIs (usually REST for everything, or GraphQL for everything) instead of blending — e.g. gRPC between internal services, REST for public APIs, GraphQL for mobile/BFF. Or comparing them on latency benchmarks alone and ignoring developer ergonomics and ecosystem.
Check your understanding
Answer these without looking back at the article.
- What is HTTP/2 multiplexing and how does gRPC benefit from it?
- Can you use gRPC from a browser? What is grpc-web?
- When would you use gRPC-Gateway to expose a REST interface over a gRPC service?
Related interview prep categories
1Want a guided curriculum order?
These modules are also sequenced in our flagship backend interview track — open it when you prefer an ordered path instead of browsing by topic.