REST vs gRPC vs GraphQL
Read a little, play a little. No scary maths, and no rush.
Last reviewed: October 2026 · report an issue
The one-line verdict
- Public APIs and simple CRUD? REST: resources at URLs, standard HTTP, understood by every tool.
- Fast, typed calls between your own services? gRPC: Protocol Buffers contracts, generated code, streaming.
- Many clients that each need different shapes of data? GraphQL: one endpoint where the client asks for exactly the fields it needs.
Each is a reasonable default in its own situation, and many companies use all three: REST for partners, gRPC inside the backend, GraphQL in front of their apps.
Three styles, three ideas
REST comes from Roy Fielding's 2000 dissertation. It describes an architectural style built from constraints such as client-server separation, stateless requests, cacheable responses and a uniform interface. In practice, that means resources at URLs (/orders/42) manipulated with HTTP methods (GET, POST, PUT, DELETE) and described by status codes.
gRPC treats the API as functions you call. You define services and messages in Protocol Buffers, the default interface definition language, and tooling generates client and server code in many languages. It runs over HTTP/2.
GraphQL gives clients one endpoint and a typed schema. The client sends a query describing exactly which fields it wants, and the response mirrors that shape.
Side by side
| REST | gRPC | GraphQL | |
|---|---|---|---|
| Shape | Resources at URLs | Methods on services | One endpoint, typed schema |
| Data format | Usually JSON | Protocol Buffers (binary) | JSON responses |
| Contract | Optional (e.g. OpenAPI) | Required .proto file |
Required schema |
| HTTP caching | Natural, with GET per URL | Not via standard HTTP caches | Needs GET or persisted queries |
| Streaming | Not built in (use SSE or WebSockets) | Built in, four call types | Subscriptions, implementation-dependent |
| Browsers | Native | Needs gRPC-Web and a proxy | Native |
| Best fit | Public APIs, CRUD | Service-to-service | Many client apps with varied needs |
REST: the web's native shape
GET /products/42 HTTP/1.1
Accept: application/json
REST reuses everything the web already has. URLs identify resources; GET is safe to repeat and cacheable, so browsers and CDNs can store responses; status codes like 404 and 429 carry meaning every developer knows. Anyone can try an endpoint with curl.
The common pain points are overfetching (the endpoint returns more fields than this screen needs) and underfetching (a screen needs product, reviews and seller, so it makes three calls). On a slow mobile network, those extra round trips add up.
gRPC: calls that feel local
syntax = "proto3";
service Pricing {
rpc GetPrice (PriceRequest) returns (PriceReply);
rpc WatchPrices (WatchRequest) returns (stream PriceReply);
}
message PriceRequest { string product_id = 1; }
message PriceReply { string product_id = 1; int64 price_paise = 2; }
From this file, tools generate a typed client and server stub in each language you use. Messages travel as compact binary Protocol Buffers over HTTP/2, and gRPC supports four kinds of methods:
- Unary: one request, one response.
- Server streaming: one request, a stream of responses (like
WatchPricesabove). - Client streaming: a stream of requests, one response.
- Bidirectional streaming: both sides stream at once.
Clients can also set a deadline: how long they're willing to wait for a call before giving up, which is essential in chains of services.
The trade-offs: browsers can't call gRPC natively, so you'd use gRPC-Web with a proxy such as Envoy, and binary messages are harder to inspect by eye than JSON.
GraphQL: ask for exactly what you need
query ProductPage {
product(id: "42") {
name
price
seller { name rating }
reviews(first: 3) { stars text }
}
}
One request returns product, seller and reviews, with only those fields. That's why GraphQL is popular in front of mobile and web apps with many different screens.
The flexibility moves work to the server, and the GraphQL project's own performance guide names the three things to plan for:
- The N+1 problem: fetching a list, then one extra lookup per item. The usual fix is batching with a tool like DataLoader.
- Caching: queries are often sent with
POST, which HTTP caches skip. UsingGETfor queries, or persisted queries (sending a hash instead of the full query), restores CDN-friendly caching. - Demand control: a client could ask for a huge, deeply nested query. Paginate list fields, limit depth and breadth, and analyze query complexity.
A worked example: one shopping platform
- Partner API for logistics companies to fetch orders: REST. Every partner can call it from any language, and
GET /orders/42caches cleanly. - Pricing service called by checkout, search and recommendations thousands of times a second: gRPC, with typed contracts, generated clients, deadlines, and streaming price updates.
- Mobile app backend serving product pages, carts and profiles: GraphQL, so each screen fetches exactly its fields in one round trip, with DataLoader and complexity limits in place.
Five questions that decide it
- Who calls the API? Outside developers favor REST; your own services favor gRPC; your own apps with many screens favor GraphQL.
- Do browsers call it directly? REST and GraphQL work natively; gRPC needs gRPC-Web and a proxy.
- How much does caching matter? REST gets HTTP caching for free; the others need deliberate setup.
- Do you need streaming? gRPC has it built in.
- What can your team operate well? A well-run REST API beats a poorly-run GraphQL server.
Honest limits
- Performance claims vary wildly. Payload size, network and implementation matter more than the style's name. Measure before choosing on speed alone.
- None of these is "REST" or "GraphQL" by label alone. Many "REST" APIs ignore caching and status codes, and many GraphQL servers ship without query limits.
- Switching later is expensive once clients depend on an API, so choose by who your callers are, not by trend.
Remember this
- REST = resources at URLs, cacheable, universal.
- gRPC = typed function calls over HTTP/2, best between services.
- GraphQL = clients pick their fields; plan for N+1, caching and query limits.
- Mixing them by audience is common and sensible.
Check your understanding
5 questions · first-try answers earn the most XP
My notes
Saved in this browser. Highlight a line above and save it, or write it in your own words.
Nothing saved yet. Your highlights will live here.
References
Finished reading?
Ticking it here also ticks the chapter in the sidebar, the section count and your streak — it is all one number.
Related chapters
Spotted a mistake or want a topic covered? Report an issue