← Home
🏗Crack System Design with DSA AnimatorSystem DesignNEW
🏗 System Design›Networking & Realtime

⚖️REST vs gRPC

Choose API protocol by ecosystem fit, latency targets, and contract strictness.

📌 Key IdeaREST (HTTP + JSON) is broadly interoperable, cache-friendly, and ideal for public/browser clients. gRPC (HTTP/2 + Protobuf) offers strongly typed contracts, smaller payloads, and first-class streaming — best for internal service-to-service calls. Most large systems use both: REST at the edge, gRPC inside.
🧩

Problem it solves

  • Microservices need a contract for how they communicate — ad-hoc JSON leads to breaking changes and integration bugs.
  • Internal high-frequency calls suffer from JSON parsing overhead and lack of streaming primitives.
  • Public APIs must work with browsers, mobile apps, third-party developers, and standard HTTP tooling.
  • Teams need to pick a protocol that matches client ecosystem, latency budget, and evolution strategy.
📖

Definition

REST models APIs as resources (/users/42) manipulated by HTTP verbs (GET, POST, PUT, DELETE) with JSON payloads. gRPC models APIs as service methods (GetUser, StreamUpdates) defined in a .proto IDL, serialized with Protocol Buffers over HTTP/2, supporting unary and streaming RPC modes.

✨

Why It Matters

  • Wrong protocol choice increases latency, payload size, and integration friction.
  • gRPC code generation from .proto catches contract mismatches at compile time.
  • REST's ubiquity makes it the default for public APIs and CDN/cache layers.
  • Hybrid architectures (REST gateway → gRPC backend) are the industry norm at scale.
🖼

Visual

⚖️ REST vs gRPC decision view
REST (HTTP/1.1 or HTTP/2 + JSON):
  resource URLs, verbs, human-readable
  browser-native, cache/proxy ecosystem

gRPC (HTTP/2 + Protobuf):
  service/method RPC, strongly typed .proto
  binary payload, low latency, streaming

Hybrid (common in production):
  REST/JSON at edge gateway -> gRPC inside service mesh
✅

When to Use

  • REST for public APIs, browser/mobile clients, webhooks, and anything needing HTTP caching/CDN.
  • gRPC for internal microservice calls requiring low latency, typed contracts, and bidirectional streaming.
  • gRPC streaming for real-time feeds, log tailing, or chat-style push between services.
  • REST + OpenAPI when API discoverability and third-party developer experience matter most.
🚫

When NOT to Use

  • gRPC directly from browser without gRPC-Web + proxy/transcoding layer.
  • REST/JSON for ultra-high-frequency internal calls where protobuf size/speed gains are significant.
  • gRPC when clients cannot generate stubs from .proto (legacy systems, quick scripts).
  • Replacing all REST with gRPC without a gateway strategy for external consumers.
💻

Code Variations

1️⃣ gRPC service definitionprotobuf
syntax = "proto3";
package user.v1;

service UserService {
  rpc GetUser(GetUserRequest) returns (UserResponse);
  rpc ListUsers(ListUsersRequest) returns (stream UserResponse);
  rpc WatchUser(WatchUserRequest) returns (stream UserEvent);
}

message GetUserRequest { string id = 1; }
message UserResponse { string id = 1; string name = 2; }
IDL-first: generate Java/Go/TS clients from .proto. Field numbers must never be reused.
2️⃣ gRPC server implementation sketchjava
@Override
public void getUser(GetUserRequest req,
                    StreamObserver<UserResponse> observer) {
  User u = userRepo.findById(req.getId()).orElseThrow();
  observer.onNext(toProto(u));
  observer.onCompleted();
}
Streaming: call onNext multiple times before onCompleted.
3️⃣ REST endpoint equivalenttext
GET  /api/v1/users/{id}          -> GetUser
GET  /api/v1/users?page=1&size=20  -> ListUsers (paginated)
SSE  /api/v1/users/{id}/events     -> WatchUser (streaming via SSE)
REST needs separate patterns (pagination, SSE) for what gRPC models as RPC modes.
4️⃣ Decision checklisttext
Choose REST when:
  - Browser/mobile public API
  - Third-party developers need curl/Postman
  - HTTP caching/CDN matters

Choose gRPC when:
  - Internal service-to-service (high QPS)
  - Strong typing + codegen valued
  - Streaming RPC needed

Hybrid when:
  - Both external REST and internal gRPC
  - Use gateway for transcoding
📊

REST vs gRPC — Side-by-Side

AspectRESTgRPC
TransportHTTP/1.1 or HTTP/2HTTP/2 (required)
Payload formatJSON (human-readable, verbose)Protobuf (binary, compact)
ContractOpenAPI/Swagger (optional, runtime validation).proto IDL (required, compile-time)
API styleResource-oriented (nouns + verbs)RPC-oriented (service methods)
Code generationOptional (OpenAPI generators)Built-in (stubs for many languages)
StreamingSSE, WebSocket, chunked (extra patterns)Unary, server, client, bidirectional streaming (native)
Browser supportNative fetch/XHRNeeds gRPC-Web + Envoy/grpc-web proxy
CachingHTTP cache headers, CDN friendlyNot cache-friendly by default
Error modelHTTP status codes + JSON bodygRPC status codes + trailing metadata
Typical latencyHigher (JSON parse + larger payload)Lower (binary + HTTP/2 multiplexing)
Best fitPublic APIs, BFF, third-party integrationsInternal service mesh, high-throughput RPC
⚖️

Key trade-offs

AreaREST advantagegRPC advantageTypical resolution
InteroperabilityWorks everywhere (curl, Postman, browser)Needs tooling/codegenREST at public edge
PerformanceGood enough for most APIs2–10x smaller payloads, faster parsegRPC for hot internal paths
Contract evolutionFlexible; optional fields commonStrict; field numbers, backward compat rulesBoth need versioning discipline
DebuggingHuman-readable JSON in logsBinary — needs grpcurl/protobuf decodeREST for external; gRPC + observability inside
Load balancingL7 HTTP LB (path/host based)L4 or gRPC-aware LB (needs connection reuse awareness)Service mesh (Istio/Linkerd) for gRPC
🔀

Common Confusions Cleared Up

Resource model vs RPC model

REST thinks in resources and representations (GET /orders/42). gRPC thinks in procedures (OrderService.GetOrder(id=42)). Neither is universally superior — match to client mental model and tooling.

JSON schema drift vs proto compile errors

REST APIs often break silently when a field is renamed — clients parse JSON defensively. gRPC .proto changes require regeneration; incompatible changes fail at build time if teams enforce proto review.

HTTP/2 multiplexing benefit

gRPC over HTTP/2 multiplexes many RPCs on one connection — reduces connection overhead for chatty services. REST over HTTP/1.1 opens many connections; HTTP/2 REST gets partial benefit without protobuf gains.

🧪

Variations / Implementations

1) REST-only (startup / public API)

Single REST API with OpenAPI spec. Simplest stack. Works for monoliths, MVPs, and public developer platforms.

2) gRPC internal + REST gateway (hybrid)

Services talk gRPC internally. API gateway (Envoy, Kong, AWS API Gateway) transcribes REST/JSON ↔ gRPC for external clients. Most common microservices pattern at scale.

3) gRPC streaming for realtime

Server streaming RPC pushes updates (StreamStockPrices). Client streaming for bulk uploads. Bidirectional for chat/collab — without WebSocket boilerplate.

⚠️

Common Mistakes / Anti-Patterns

  • gRPC from browser without gRPC-Web proxy.
  • Breaking .proto field numbers or reusing tag numbers.
  • Giant JSON payloads on hot internal paths when gRPC would cut bandwidth 5x.
  • No API versioning strategy (REST /v1/ or proto package versioning).
  • Ignoring gRPC load balancing — sticky connections to wrong backend.
  • Replacing REST entirely without considering external client ecosystem.
🎤

Interview Q&A

🔮

Likely Follow-up Questions

  • What is gRPC-Web and when do you need it?
  • How does a service mesh help with gRPC load balancing?
  • REST vs GraphQL — where does each fit?
🧾

Quick Cheat Sheet

REST best atPublic APIs, browser, caching, simplicity.
gRPC best atInternal typed RPC, streaming, low latency.
HybridREST at edge gateway, gRPC inside mesh.
Proto ruleNever reuse field numbers.
Browser gRPCRequires gRPC-Web + proxy.
PayloadJSON (REST) vs Protobuf (gRPC).
🔗

Related Topics