Picking an API protocol shapes your client experience, your throughput, your tooling, and your caching story for years. "We'll use REST" is the lazy default, often the wrong one. gRPC is 7× faster but kills browser usability. GraphQL solves over-fetching but introduces N+1 query problems. Each protocol was designed to solve a specific pain — know which pain you have.
02
The three at a glance
Protocol
Encoding
Schema
Ideal use
REST
JSON over HTTP/1.1 or /2
Optional (OpenAPI / Swagger)
Public APIs, CRUD, browser clients
GraphQL
JSON over HTTP (usually POST /graphql)
Required (typed schema)
Client-flexible queries, mobile data-saving, aggregation layer
Resources addressed by URL, verbs (GET/POST/PUT/DELETE) as operations. Stateless, cacheable, human-readable.
Strengths: every developer knows it. HTTP caching works out of the box. Browsers handle it natively. Tools (curl, Postman, jq) just work.
Weaknesses:
Over-fetching — you wanted the user's name; you got their entire profile + preferences + metadata. Mobile clients pay for bytes they don't use.
Under-fetching — your screen needs 3 resources; client makes 3 round-trips. Common fix: build a BFF (backend-for-frontend) that aggregates.
No schema enforcement by default — typo in a field name = runtime bug. OpenAPI helps but isn't universal.
04
GraphQL — ask for exactly what you need
One endpoint. Client sends a query specifying exactly which fields of which types it wants. Server returns exactly that — no more, no less.
{
user(id: 42) {
name
posts(limit: 5) {
title
comments { author, text }
}
}
}
One round-trip replaces 3-5. Mobile clients ship far fewer bytes. Backend can evolve fields freely — adding a field doesn't break old clients because they don't ask for it.
Catches:
N+1 query problem — "posts + comments" can turn into 1 + N + M DB queries. Requires DataLoader-style batching.
Caching is hard — GET-cacheable only via persisted queries. Browsers/CDNs don't natively cache POSTs.
Rate limiting is hard — cost can't be determined by path; needs query complexity analysis.
Authorization is field-level — every field needs permission checks. More complex than REST's endpoint-level model.
Best for: client-flexible data (mobile apps), aggregator layers over multiple microservices, internal dashboards. Shopify, GitHub, Facebook expose GraphQL APIs.
05
Deep dive — gRPC, the performance choice
gRPC uses Protocol Buffers (binary, schema-defined) over HTTP/2. Compared to REST+JSON:
~5–7× smaller payloads (binary vs text).
~3–5× faster to serialize/parse (native-typed decoding vs JSON tree walking).
Multiplexed over HTTP/2 — 100 concurrent calls on one TCP connection.
Code generation from .proto for every major language. Typed client in seconds.
But: it doesn't work in browsers natively (needs gRPC-Web proxy). Intermediaries (LBs, debuggers, humans) can't read requests without protoc. HTTP caching doesn't apply. So gRPC's sweet spot is internal, high-RPS service-to-service. External APIs usually stay REST or GraphQL.
The modern stack
REST for public APIs. GraphQL as the aggregation layer for mobile + SPA clients. gRPC between internal services. Each tool plays to its strength; hybrid stacks are normal at scale.
Benchmark — Same Payload, Different ProtocolsReal-world numbers
Metric
REST + JSON
GraphQL + JSON
gRPC + Protobuf
Payload size (1 user obj)
~450 B
~280 B (only requested fields)
~80 B
Serialize CPU
~3 μs
~3 μs
~0.5 μs
P50 latency (intra-DC)
~1.2 ms
~1.5 ms
~0.3 ms
Throughput per core
~25k RPS
~18k RPS
~80k RPS
Browser support
Native
Native (via fetch)
gRPC-Web proxy required
Streaming
SSE bolt-on
Subscriptions (WS)
Native bidirectional
Tooling maturity
Excellent (curl, Postman)
Good (GraphiQL)
Hard to inspect (binary)
06
Real-world
Stripe
REST + OpenAPI
Every Stripe API is REST. Strict versioning, webhooks. The gold standard for public REST APIs.
GitHub
REST v3 + GraphQL v4
Both supported. GraphQL endpoint lets third-party clients fetch exactly the fields they need.
Shopify Storefront
GraphQL
Their public API is GraphQL-first — allows themes and headless storefronts to query what they need.
Google / Netflix internal
gRPC
Inside both, almost every service call is gRPC. Public-facing APIs are usually REST with an internal gRPC implementation.
07
Used in problems
News feed backend uses gRPC between microservices; exposes REST/GraphQL to mobile clients. E-commerce uses REST publicly + gRPC internally. Uber uses gRPC for driver app ↔ dispatch (low-latency streaming).