gRPC is the high-performance alternative to REST that powers communication at Google, Netflix, and Uber. It uses Protocol Buffers (protobuf) for compact binary serialization and HTTP/2 for multiplexed streams — making it 3-10x faster than JSON over HTTP/1.1. This guide covers everything from protobuf basics to production patterns for gRPC services.
gRPC vs REST: When to Choose What
| Factor | gRPC | REST (JSON) |
| Protocol | HTTP/2 (multiplexed, binary) | HTTP/1.1 or HTTP/2 (text-based JSON) |
| Serialization | Protocol Buffers (binary, 3-10x smaller) | JSON (text, human-readable) |
| Contract | .proto files (strongly typed, code-generated) | OpenAPI/Swagger (optional, often manual) |
| Streaming | Built-in: unary, server, client, bidirectional | Server-Sent Events, WebSocket (separate setup) |
| Browser Support | Limited (needs gRPC-Web proxy) | Native (fetch, XMLHttpRequest) |
| Debugging | Harder (binary, needs grpcurl or BloomRPC) | Easy (curl, browser DevTools, Postman) |
| Performance | 3-10x faster, 3-10x smaller payload | Good enough for most use cases |
| Best For | Internal microservices, high-throughput RPC | Public APIs, browser-to-server communication |
Defining a gRPC Service in Protobuf
// users.proto — a complete gRPC service definition
syntax = "proto3";
package users.v1;
// Request/Response messages
message GetUserRequest {
string user_id = 1; // Field numbers (1, 2, 3...) determine wire format
}
message User {
string user_id = 1;
string email = 2;
string display_name = 3;
repeated string roles = 4; // repeated = array/list
optional string avatar_url = 5; // optional = can be unset
}
message ListUsersRequest {
int32 page_size = 1;
string page_token = 2;
}
message ListUsersResponse {
repeated User users = 1;
string next_page_token = 2;
}
// The service: what RPCs are available
service UserService {
// Unary: one request → one response
rpc GetUser(GetUserRequest) returns (User);
// Server streaming: one request → many responses
rpc ListUsers(ListUsersRequest) returns (stream User);
// Client streaming: many requests → one response
rpc BatchCreateUsers(stream CreateUserRequest) returns (BatchCreateUsersResponse);
// Bidirectional streaming: many ↔ many
rpc Chat(stream ChatMessage) returns (stream ChatMessage);
}
// Generate code: protoc --go_out=. --go-grpc_out=. users.proto
// For Node.js: @grpc/grpc-js + @grpc/proto-loader
gRPC Streaming Patterns
| Pattern | Use Case | Example |
| Unary (1 req → 1 resp) | Standard API calls | GetUser(id), CreateOrder(order) |
| Server Streaming (1 req → N resp) | Large result sets, real-time feeds | ListUsers (stream results), SubscribeToEvents |
| Client Streaming (N req → 1 resp) | Uploading data, batching | UploadFile (stream chunks), BatchImport |
| Bidirectional (N ↔ N) | Real-time two-way communication | Chat, collaborative editing, game state sync |
gRPC in Production: Essential Patterns
| Pattern | Why | Implementation |
| Deadlines / Timeouts | Prevents hanging requests; every gRPC call must have a deadline | Set deadline in metadata: 500ms for internal, 2s for external |
| Retries with Backoff | Handles transient network failures | gRPC built-in retry policy config in service config |
| Interceptors (Middleware) | Auth, logging, tracing, rate limiting | UnaryServerInterceptor / StreamServerInterceptor |
| Load Balancing | Distribute traffic across gRPC backends | Client-side (gRPC resolver) or proxy-based (Envoy, Linkerd) |
| Health Checking | K8s/load balancer needs to know service is healthy | Implement grpc.health.v1.Health service |
| Reflection | Enable grpcurl and debugging tools | Register reflection service in server |
Bottom line: Use gRPC for internal service-to-service communication where performance matters — microservices, data-intensive backends, and real-time streaming. Use REST for public APIs, browser-facing endpoints, and when broad ecosystem compatibility (curl, Postman, web browsers) is needed. The two are not mutually exclusive — many teams use gRPC internally and expose REST externally via an API gateway (gRPC-gateway or Envoy). See also: tRPC vs GraphQL vs REST and API Design Patterns.