gRPC Cheatsheet
Basics
Use this gRPC reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
gRPC Cheatsheet
gRPC is a high-performance, open-source RPC framework developed by Google. This programming cheatsheet is a quick developer reference for reading .proto files, choosing unary vs streaming RPCs, setting deadlines, handling errors, and wiring clients in production services.
For adjacent syntax references, use the Python cheatsheet for generated Python clients, the React cheatsheet when a frontend calls a gateway, the SQL cheatsheet for service-backed data access, and the Git cheatsheet while versioning .proto contracts.
| Property | Detail |
|---|---|
| Transport | HTTP/2 (multiplexed, binary framing) |
| Serialization | Protocol Buffers v3 (binary, ~3-10x smaller than JSON) |
| Streaming | Unary, server-streaming, client-streaming, bidirectional |
| Languages | Go, Java, Python, Node.js, C++, C#, Ruby, PHP, Dart, Kotlin… |
| Port convention | 50051 (default for most examples) |
Core Concepts
.protofile — defines services (methods) and messages (data shapes) in a language-neutral IDL.protoc+ plugin — compiles.proto→ language-specific stubs (do not edit generated files).- Stub / channel — the client holds a channel (connection to a server address) and creates stubs from it.
- Service — a named collection of RPC methods.
- Message — a strongly typed data structure (equivalent to a request/response body).
- Deadline / timeout — every call should set one; gRPC propagates them across service hops.
- Metadata — key-value pairs sent with a call (headers/trailers), analogous to HTTP headers.
RPC Method Types
| Type | Client sends | Server sends | .proto syntax |
|---|---|---|---|
| Unary | 1 message | 1 message | rpc Foo(Req) returns (Res) |
| Server streaming | 1 message | N messages (stream) | rpc Foo(Req) returns (stream Res) |
| Client streaming | N messages (stream) | 1 message | rpc Foo(stream Req) returns (Res) |
| Bidirectional streaming | N messages (stream) | N messages (stream) | rpc Foo(stream Req) returns (stream Res) |
Installation (Node.js)
# Runtime library — used at runtime by servers and clients npm install @grpc/grpc-js # Protobuf loader — loads .proto files dynamically at runtime npm install @grpc/proto-loader # OR: code-generation path (recommended for production) npm install -g grpc-tools # installs protoc + grpc_node_plugin npm install google-protobuf # generated message helpers
Toolchain Overview
yourservice.proto
│
▼ protoc --js_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_tools_node_protoc_plugin`
│
├── yourservice_pb.js (message classes)
└── yourservice_grpc_pb.js (service stubs)Dynamic loading (skip codegen, good for prototyping):
const grpc = require('@grpc/grpc-js'); const protoLoader = require('@grpc/proto-loader'); const packageDef = protoLoader.loadSync('service.proto', { keepCase: true, // preserve field names as-is longs: String, // represent int64 as String (avoids JS precision loss) enums: String, // enum values as strings defaults: true, // fill in default values oneofs: true, // virtual oneof fields }); const proto = grpc.loadPackageDefinition(packageDef);
Other Languages at a Glance
The rest of this sheet targets Node.js (@grpc/grpc-js); the wire protocol, status codes, deadlines, and metadata semantics are identical everywhere.
| Language | Install | Codegen |
|---|---|---|
| Go | go get google.golang.org/grpc | protoc --go_out=. --go-grpc_out=. service.proto (plugins: protoc-gen-go, protoc-gen-go-grpc) |
| Python | pip install grpcio grpcio-tools | python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. service.proto |
| Java | io.grpc:grpc-netty-shaded + grpc-protobuf + grpc-stub | protoc-gen-grpc-java via the Gradle/Maven protobuf plugin |
// Go — unary client (grpc.NewClient replaced grpc.Dial in grpc-go 1.63+) conn, err := grpc.NewClient("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials())) defer conn.Close() client := pb.NewUserServiceClient(conn) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() res, err := client.GetUser(ctx, &pb.GetUserRequest{UserId: 42})
# Python — unary client import grpc import service_pb2, service_pb2_grpc with grpc.insecure_channel("localhost:50051") as channel: stub = service_pb2_grpc.UserServiceStub(channel) res = stub.GetUser(service_pb2.GetUserRequest(user_id=42), timeout=5)
- Browsers cannot speak native gRPC (no client access to HTTP/2 trailers) — use grpc-web (
protoc-gen-grpc-web+ the Envoy grpc-web filter), Connect (@connectrpc/connect-web), or a REST gateway (grpc-gatewayin Go).
Channel and Credentials
const grpc = require('@grpc/grpc-js'); // Insecure (dev/internal) const creds = grpc.credentials.createInsecure(); // TLS with system roots (production, no client cert) const creds = grpc.credentials.createSsl(); // mTLS — custom CA + client cert/key const creds = grpc.credentials.createSsl( rootCerts, // Buffer — CA cert (or null for system roots) privateKey, // Buffer — client private key certChain, // Buffer — client certificate chain ); // Combined: TLS + call credentials (e.g., token auth) const callCreds = grpc.credentials.createFromMetadataGenerator((params, cb) => { const meta = new grpc.Metadata(); meta.add('authorization', 'Bearer ' + getToken()); cb(null, meta); }); const combinedCreds = grpc.credentials.combineChannelCredentials(creds, callCreds); // Create a channel (not a stub yet) const channel = new grpc.Channel('localhost:50051', creds, {});
Channel Options (Common)
const options = { 'grpc.keepalive_time_ms': 10_000, // send ping every 10s 'grpc.keepalive_timeout_ms': 5_000, // wait 5s for ping ack 'grpc.keepalive_permit_without_calls': 1, // ping even with no active calls 'grpc.max_receive_message_length': 4 * 1024 * 1024, // 4 MB (default 4 MB) 'grpc.max_send_message_length': 4 * 1024 * 1024, 'grpc.enable_retries': 1, 'grpc.service_config': JSON.stringify({ methodConfig: [{ name: [{}], retryPolicy: { maxAttempts: 4, initialBackoff: '0.1s', maxBackoff: '1s', backoffMultiplier: 2, retryableStatusCodes: ['UNAVAILABLE'], }, }], }), };
Status Codes Quick Reference
| Code | Number | Meaning |
|---|---|---|
OK | 0 | Success |
CANCELLED | 1 | Operation cancelled by client |
UNKNOWN | 2 | Unknown error |
INVALID_ARGUMENT | 3 | Bad request data |
DEADLINE_EXCEEDED | 4 | Timeout |
NOT_FOUND | 5 | Entity not found |
ALREADY_EXISTS | 6 | Duplicate |
PERMISSION_DENIED | 7 | Not allowed |
RESOURCE_EXHAUSTED | 8 | Rate limited / quota |
FAILED_PRECONDITION | 9 | System not in correct state |
ABORTED | 10 | Concurrency conflict |
OUT_OF_RANGE | 11 | Value outside valid range |
UNIMPLEMENTED | 12 | Method not implemented |
INTERNAL | 13 | Internal server error |
UNAVAILABLE | 14 | Server unreachable / transient |
DATA_LOSS | 15 | Unrecoverable data loss/corruption |
UNAUTHENTICATED | 16 | Missing/invalid credentials |
Gotchas
int64 / uint64 fields — JavaScript cannot represent these exactly as numbers. Set
longs: StringinprotoLoader.loadSyncto receive them as strings.
Generated file edits — never edit
*_pb.js/*_grpc_pb.jsfiles; they are overwritten on everyprotocrun.
Default channel options —
grpc.max_receive_message_lengthdefaults to 4 MB. Large payloads (file transfers, big result sets) require raising this option on both client and server.
Graceful shutdown — call
server.tryShutdown(cb)(waits for in-flight calls) rather thanserver.forceShutdown()in production.