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.

PropertyDetail
TransportHTTP/2 (multiplexed, binary framing)
SerializationProtocol Buffers v3 (binary, ~3-10x smaller than JSON)
StreamingUnary, server-streaming, client-streaming, bidirectional
LanguagesGo, Java, Python, Node.js, C++, C#, Ruby, PHP, Dart, Kotlin…
Port convention50051 (default for most examples)

Core Concepts

  • .proto file — 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

TypeClient sendsServer sends.proto syntax
Unary1 message1 messagerpc Foo(Req) returns (Res)
Server streaming1 messageN messages (stream)rpc Foo(Req) returns (stream Res)
Client streamingN messages (stream)1 messagerpc Foo(stream Req) returns (Res)
Bidirectional streamingN 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.

LanguageInstallCodegen
Gogo get google.golang.org/grpcprotoc --go_out=. --go-grpc_out=. service.proto (plugins: protoc-gen-go, protoc-gen-go-grpc)
Pythonpip install grpcio grpcio-toolspython -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. service.proto
Javaio.grpc:grpc-netty-shaded + grpc-protobuf + grpc-stubprotoc-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-gateway in 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

CodeNumberMeaning
OK0Success
CANCELLED1Operation cancelled by client
UNKNOWN2Unknown error
INVALID_ARGUMENT3Bad request data
DEADLINE_EXCEEDED4Timeout
NOT_FOUND5Entity not found
ALREADY_EXISTS6Duplicate
PERMISSION_DENIED7Not allowed
RESOURCE_EXHAUSTED8Rate limited / quota
FAILED_PRECONDITION9System not in correct state
ABORTED10Concurrency conflict
OUT_OF_RANGE11Value outside valid range
UNIMPLEMENTED12Method not implemented
INTERNAL13Internal server error
UNAVAILABLE14Server unreachable / transient
DATA_LOSS15Unrecoverable data loss/corruption
UNAUTHENTICATED16Missing/invalid credentials

Gotchas

int64 / uint64 fields — JavaScript cannot represent these exactly as numbers. Set longs: String in protoLoader.loadSync to receive them as strings.

Generated file edits — never edit *_pb.js / *_grpc_pb.js files; they are overwritten on every protoc run.

Default channel optionsgrpc.max_receive_message_length defaults 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 than server.forceShutdown() in production.