🔌

Top 46 gRPC Interview Questions & Answers (2026)

46 Questions 20 Beginner 16 Intermediate 10 Advanced

About gRPC

Top 50 gRPC interview questions covering Protocol Buffers, streaming, HTTP/2, service design, authentication, and microservices integration. Companies hiring for gRPC roles test this knowledge at every stage — from first-round screens that check the basics to final-round conversations about real-world trade-offs.

What to Expect in a gRPC Interview

Expect a mix of conceptual and practical gRPC questions: clear definitions and core-concept checks for junior roles, hands-on scenario questions for mid-level roles, and architecture or trade-off discussions for senior roles. Interviewers usually move from foundational topics toward the kind of problems you'd actually face on the job.

How to Use This Guide

Work through the gRPC questions in order — Beginner, then Intermediate, then Advanced — so each concept builds on the last. Every question has its own page; bookmark the ones that trip you up and revisit them the day before your interview.

Curated by Tech Baithak Editorial Team  ·  Last updated: June 2026

Beginner 20 questions

Core concepts every gRPC developer must know.

01

What is gRPC?

gRPC is an open-source, high-performance Remote Procedure Call (RPC) framework developed by Google and now hosted under the Cloud Native Computing Foundation (CNCF). It allows a client to call methods on a remote server as if they were local functions, handling the underlying network communication, serialization, and transport automatically. gRPC uses Protocol Buffers (Protobuf) as its Interface Definition Language (IDL) and wire format, and runs over HTTP/2 for transport. It supports bidirectional streaming, strong typing, code generation in 11+ languages, and built-in features like authentication, load balancing, and deadline propagation. It is widely used for microservice-to-microservice communication where performance and type safety are critical.

Open this question on its own page
02

What does gRPC stand for?

The "g" in gRPC officially stands for different things in each release — it's a running joke in the gRPC project. In the first release, it stood for gRPC itself (recursive acronym). Subsequent releases have had the "g" mean: "good", "green", "glorious", etc. The "RPC" part always stands for Remote Procedure Call, the classic concept of executing a procedure (function) on a remote computer as if it were a local call. So while the "g" is playful, the core meaning is a Google-originated Remote Procedure Call framework. It was publicly released by Google in 2015 and became a CNCF graduated project in 2019.

Open this question on its own page
03

What is Protocol Buffers (Protobuf)?

Protocol Buffers (Protobuf) is a language-neutral, platform-neutral, binary serialization format developed by Google. You define data structures (messages) and service interfaces in .proto files using a simple IDL syntax, then compile them with the protoc compiler to generate strongly-typed data access classes in your target language (Go, Java, Python, C++, etc.). Protobuf is significantly more efficient than JSON or XML: it produces smaller binary output (3–10x less data), faster serialization/deserialization (5–100x faster), and provides compile-time type safety. The tradeoff: binary format is not human-readable, unlike JSON. Protobuf is used by gRPC as both the service definition language and the over-the-wire serialization format.

Open this question on its own page
04

How does gRPC differ from REST?

Key differences: (1) Protocol — REST typically uses HTTP/1.1; gRPC uses HTTP/2 with multiplexing and binary framing; (2) Data format — REST commonly uses JSON (text, human-readable); gRPC uses Protobuf (binary, compact, faster); (3) Contract — REST is loosely defined (OpenAPI is optional); gRPC requires a .proto file contract (mandatory, strongly typed); (4) Code generation — gRPC auto-generates client and server stubs; REST requires manual client implementation or tools like OpenAPI Generator; (5) Streaming — gRPC natively supports server/client/bidirectional streaming; REST only supports request-response; (6) Browser support — REST works natively in browsers; gRPC requires gRPC-Web (a browser-compatible variant); (7) Performance — gRPC is typically 7–10x faster than REST for equivalent operations.

Open this question on its own page
05

What is a `.proto` file?

A .proto file is the Interface Definition Language (IDL) source file for Protocol Buffers and gRPC. It defines: (1) Messages — data structures with typed fields, e.g., message User { int32 id = 1; string name = 2; }; (2) Services — collections of RPC methods, e.g., service UserService { rpc GetUser(GetUserRequest) returns (User); }; (3) Enums, oneof fields, map types, nested messages. The protoc compiler reads .proto files and generates language-specific code (stubs, message classes). The syntax = "proto3"; declaration at the top specifies the Protobuf version. Field numbers (e.g., = 1) identify fields in the binary encoding — they must never change once used in production, as they're part of the wire format.

Open this question on its own page
06

What are the four types of gRPC service methods?

gRPC defines four communication patterns: (1) Unary RPC — the client sends one request and gets one response, like a function call: rpc GetUser(Request) returns (Response); (2) Server Streaming RPC — the client sends one request and gets a stream of responses: rpc ListUsers(Request) returns (stream Response); (3) Client Streaming RPC — the client sends a stream of requests and gets one response: rpc UploadFile(stream Chunk) returns (Response); (4) Bidirectional Streaming RPC — both client and server send streams of messages independently: rpc Chat(stream Message) returns (stream Message). The appropriate type depends on the use case: unary for simple lookups, server streaming for large result sets, client streaming for uploads, bidirectional for real-time interactive communication.

Open this question on its own page
07

What is unary RPC?

Unary RPC is the simplest and most common gRPC pattern — the client sends a single request and waits for a single response from the server, similar to a traditional function call. It is defined in a .proto file as: rpc GetProduct(GetProductRequest) returns (Product);. When the client calls this method, gRPC serializes the request to Protobuf, sends it over HTTP/2 to the server, the server processes it, serializes the response, and returns it. The client receives the response and deserializes it. Unary RPC is best for lookups, CRUD operations, and any request-response interaction. It behaves similarly to REST GET/POST but with Protobuf serialization and HTTP/2 transport benefits.

Open this question on its own page
08

What is server streaming RPC?

Server streaming RPC allows the client to send one request and receive a stream of multiple responses from the server. Defined as: rpc ListTransactions(DateRange) returns (stream Transaction);. The server writes multiple messages to the stream as they become available, and the client reads them one by one as they arrive. The server signals completion by closing the stream. Server streaming is ideal for: returning large result sets without buffering everything in memory (e.g., paginating a large database query), pushing live updates in response to a subscription request (e.g., subscribing to price updates), or streaming file/media content. The client reads from the stream using a for-range loop (Go) or async iterator (Python) until the stream ends.

Open this question on its own page
09

What is client streaming RPC?

Client streaming RPC allows the client to send a stream of multiple request messages to the server, which processes them and returns one response after the client closes the stream. Defined as: rpc UploadSensorData(stream SensorReading) returns (UploadSummary);. The client sends messages one by one, then closes the stream. The server reads all messages, accumulates them, and returns a single summary response. Use cases: file uploads sent in chunks (the server assembles them), aggregating time-series data (the server computes statistics after receiving all readings), batch operations (the client streams many records, the server processes and confirms). The server waits until the client closes its sending stream before sending its response.

Open this question on its own page
10

What is bidirectional streaming RPC?

Bidirectional streaming RPC allows both client and server to send independent streams of messages to each other simultaneously. Defined as: rpc RouteChat(stream RouteNote) returns (stream RouteNote);. Both sides read from and write to their respective streams in any order — neither side needs to finish before the other responds. The streams are independent, operating over a single HTTP/2 connection. Use cases: real-time chat applications, multiplayer game state synchronization, bidirectional telemetry (client streams sensor data, server streams commands back), collaborative editing. Bidirectional streaming is gRPC's most powerful but most complex pattern, requiring careful coordination of when each side sends, receives, and closes its stream.

Open this question on its own page
11

What is HTTP/2 and why does gRPC use it?

HTTP/2 is the second major version of HTTP, bringing fundamental improvements over HTTP/1.1. gRPC uses HTTP/2 because of: (1) Multiplexing — multiple requests/streams can be in flight simultaneously on a single TCP connection, eliminating head-of-line blocking; gRPC streams map to HTTP/2 streams; (2) Binary framing — HTTP/2 uses binary frames instead of text, enabling efficient parsing; (3) Header compression (HPACK) — eliminates repetitive header overhead across requests; (4) Flow control — per-stream flow control prevents fast senders from overwhelming slow receivers; (5) Server push (though gRPC doesn't use this). HTTP/2 enables gRPC's four service types: multiplexing allows simultaneous streams, and binary framing supports both text and binary payloads efficiently. All gRPC connections use HTTP/2 — gRPC cannot work over HTTP/1.1.

Open this question on its own page
12

What is the role of a gRPC stub?

A gRPC stub (also called a client stub or simply "client") is the auto-generated client-side code that provides a local interface to call remote gRPC service methods as if they were local functions. When you compile a .proto file with protoc and the gRPC plugin, it generates stub code in your target language. The stub handles: serializing method arguments to Protobuf, establishing the HTTP/2 connection, sending the request, receiving and deserializing the response, managing stream lifecycle, and propagating errors and metadata. There are two types of stubs in some languages: blocking stubs (synchronous calls that block the thread until the response arrives) and async stubs (non-blocking calls using futures, callbacks, or coroutines). The stub abstracts all network details, letting developers call remote methods with the same syntax as local ones.

Open this question on its own page
13

How do you define a gRPC service in a `.proto` file?

A gRPC service is defined in a .proto file using the service keyword. Example: syntax = "proto3"; package example; service ProductService { rpc GetProduct(GetProductRequest) returns (Product); rpc ListProducts(ListProductsRequest) returns (stream Product); rpc CreateProduct(CreateProductRequest) returns (Product); } message Product { int32 id = 1; string name = 2; float price = 3; } message GetProductRequest { int32 id = 1; }. Key rules: each rpc method has exactly one request type and one return type; streaming is indicated with the stream keyword before the type; field numbers (e.g., = 1) must be unique within a message and are permanent once deployed; use package to namespace your messages. After defining the service, run protoc --grpc_out=. --go_out=. service.proto to generate language-specific code.

Open this question on its own page
14

What is a gRPC channel?

A gRPC channel is a connection abstraction representing a virtual connection to a gRPC server endpoint. It encapsulates the HTTP/2 connection(s) to the server and manages connection lifecycle, reconnection, load balancing, and channel state. You create a channel with the server address: channel = grpc.insecure_channel('localhost:50051') (Python) or conn, _ := grpc.Dial('localhost:50051', grpc.WithInsecure()) (Go). The channel is lazy — it doesn't connect immediately but on the first RPC call. A channel goes through states: IDLE, CONNECTING, READY, TRANSIENT_FAILURE, SHUTDOWN. You create stubs from a channel: stub = ProductServiceStub(channel). Channels are expensive to create (TCP handshake, TLS negotiation, HTTP/2 setup), so they should be long-lived and reused across multiple calls, not created per request.

Open this question on its own page
15

What are gRPC metadata?

gRPC metadata is arbitrary key-value data sent alongside RPC calls, analogous to HTTP headers. Metadata allows clients and servers to exchange information outside the main request/response messages. Common uses: authentication tokens (authorization: Bearer xxx), request IDs for tracing, custom context (tenant ID, API version), and load balancing hints. Metadata is sent in two phases: initial metadata (before response data, like HTTP headers) and trailing metadata (after response data, like HTTP trailers — used for status codes and timing). Keys ending in -bin are binary values (base64 encoded); others are ASCII strings. In Go: md := metadata.Pairs("authorization", "Bearer token"); ctx := metadata.NewOutgoingContext(ctx, md). Servers can read metadata with metadata.FromIncomingContext(ctx).

Open this question on its own page
16

What is the gRPC status code?

gRPC uses a standardized set of status codes to communicate the outcome of an RPC call, similar to HTTP status codes but with different semantics. Key codes: OK (0, success), CANCELLED (1, client cancelled), UNKNOWN (2, general server error), INVALID_ARGUMENT (3, bad request data), NOT_FOUND (5, resource not found), ALREADY_EXISTS (6, creation conflict), PERMISSION_DENIED (7, authorization failure), RESOURCE_EXHAUSTED (8, quota/rate limit exceeded), FAILED_PRECONDITION (9, operation not valid in current state), UNAUTHENTICATED (16, missing/invalid credentials), INTERNAL (13, server-side error). Status codes are sent in HTTP/2 trailing metadata as grpc-status. A status also includes an optional human-readable grpc-message string and structured error details.

Open this question on its own page
17

How does gRPC handle errors?

gRPC errors are represented by a status containing a StatusCode and an optional message. When an RPC fails, the client receives an error object that wraps these. In Go: st, ok := status.FromError(err); if ok { fmt.Println(st.Code(), st.Message()) }. Servers return errors using the status API: return nil, status.Errorf(codes.NotFound, "user %d not found", id). For richer error details, gRPC supports error details via the google.rpc.Status Protobuf message, which can carry structured error information (field violations, retry info, resource info). The google.rpc package provides standard error detail types: BadRequest with field violations for validation errors, RetryInfo for temporary failures, and ErrorInfo for domain-specific errors. Avoid using UNKNOWN — always use the most specific status code.

Open this question on its own page
18

What are the advantages of gRPC over REST?

gRPC advantages over REST: (1) Performance — Protobuf binary serialization is significantly faster and produces smaller payloads than JSON; HTTP/2 multiplexing eliminates connection overhead; (2) Type safety — strict .proto contracts with code generation catch type mismatches at compile time; REST JSON is untyped by default; (3) Bidirectional streaming — native support for all streaming patterns; REST only supports one-shot request-response; (4) Code generation — client and server stubs are auto-generated in 11+ languages; (5) Deadline/timeout propagation — deadlines automatically cancel the entire RPC chain; (6) Built-in features — authentication, load balancing, health checking, reflection are part of the framework; (7) Strong backward compatibility story — Protobuf field numbering rules enable safe schema evolution. Disadvantages: not human-readable, requires gRPC-Web for browsers, steeper learning curve.

Open this question on its own page
19

What are the disadvantages of gRPC?

gRPC has notable limitations: (1) Browser support — gRPC requires HTTP/2 with trailers, which browsers don't natively support for XHR/Fetch; gRPC-Web (with a proxy) is required for browser clients, adding infrastructure complexity; (2) Not human-readable — Protobuf binary messages can't be inspected with curl or browser DevTools; debugging requires tools like grpcurl, Postman, or Bloomrpc; (3) Learning curve — Proto IDL, code generation, and gRPC concepts require upfront learning; REST with JSON is more approachable; (4) Ecosystem maturity — REST tooling (API gateways, monitoring, testing) is more mature and widely supported; (5) No standard caching — HTTP GET-based REST caches naturally via CDN/proxies; gRPC POST-based requests don't cache easily; (6) Protobuf schema management — maintaining .proto files, breaking change prevention, and schema registry requires discipline and tooling; (7) Limited support in some languages — gRPC support quality varies across language ecosystems.

Open this question on its own page
20

What languages does gRPC support?

gRPC officially supports 11 programming languages with maintained implementations: C++, Java (including Android), Python, Go, Ruby, C# (.NET), Node.js, PHP, Dart, Kotlin, and Objective-C (iOS). Additionally, the community maintains implementations for Rust (tonic), Swift (grpc-swift), Haskell, Erlang, and others. The Go and Java implementations are considered the most mature and performant. Go has particularly excellent gRPC support through the google.golang.org/grpc package and protoc-gen-go-grpc plugin. The protoc compiler generates language-specific stubs for each supported language from the same .proto source, enabling polyglot microservice architectures where services in different languages communicate seamlessly.

Open this question on its own page
Intermediate 16 questions

Practical knowledge for developers with hands-on experience.

01

How does gRPC handle authentication?

gRPC supports multiple authentication mechanisms: (1) SSL/TLS — the default for production; encrypt all traffic and optionally authenticate the server using TLS certificates. Use credentials.NewClientTLSFromFile(certFile, "") in Go; (2) Token-based (JWT/OAuth2) — the client sends a token in metadata (authorization: Bearer xxx). gRPC provides a PerRPCCredentials interface that automatically attaches tokens to every call; (3) mTLS (Mutual TLS) — both client and server present certificates, providing bidirectional authentication suitable for service-to-service communication in zero-trust networks; (4) Google token-based — using service account credentials for Google Cloud APIs; (5) Interceptors — server-side unary/stream interceptors validate authentication metadata before passing to handler: func AuthInterceptor(ctx, req, info, handler) { token := metadata.ValueFromIncomingContext(ctx, "authorization"); verify(token); return handler(ctx, req) }.

Open this question on its own page
02

What is a gRPC interceptor?

A gRPC interceptor is middleware that intercepts RPC calls on the client or server side, similar to HTTP middleware. Interceptors allow cross-cutting concerns to be implemented once and applied globally. Server-side interceptors: UnaryInterceptor intercepts unary calls, StreamInterceptor intercepts streaming calls. Common uses: authentication (validate tokens), authorization (check permissions), logging (log request/response/duration), rate limiting, request validation, distributed tracing (inject trace IDs), and caching. In Go: grpc.NewServer(grpc.UnaryInterceptor(myInterceptor)). Client-side interceptors (called dialers) intercept outgoing calls — useful for adding auth tokens, retrying failed calls, or adding tracing headers. Multiple interceptors are chained using interceptor chain utilities like grpc_middleware.ChainUnaryServer(...interceptors).

Open this question on its own page
03

How do you implement streaming in gRPC?

Server streaming example in Go: define rpc ListItems(ListRequest) returns (stream Item), implement as func (s *server) ListItems(req *ListRequest, stream pb.ItemService_ListItemsServer) error { for _, item := range items { if err := stream.Send(item); err != nil { return err } }; return nil }. The server loops and calls stream.Send() for each message. Client reads: for { item, err := stream.Recv(); if err == io.EOF { break }; use(item) }. Bidirectional streaming: both sides call Send() and Recv() concurrently, typically in separate goroutines. Key considerations: error handling on every send/receive, context cancellation to detect client disconnection, backpressure via HTTP/2 flow control (slowing sends when the receiver is slow), and deadline propagation (streams respect the parent context deadline).

Open this question on its own page
04

What is gRPC-web and why is it needed?

gRPC-Web is a variant of the gRPC protocol designed for use in web browsers. Standard gRPC requires HTTP/2 features (trailing headers) that browser XHR/Fetch APIs don't expose, making it impossible to use gRPC directly from browser JavaScript. gRPC-Web works by: (1) Using HTTP/1.1 or HTTP/2 without trailing headers, using a different framing; (2) Requiring an Envoy proxy (or grpc-web proxy) between browser clients and gRPC servers — the proxy translates gRPC-Web protocol to standard gRPC; (3) Supporting only unary and server-streaming (client streaming and bidirectional streaming are not supported). The @improbable-eng/grpc-web or official grpc-web npm package provides the browser client. For applications that need full streaming in the browser, WebSockets or native gRPC (via Envoy) are alternatives. gRPC-Web is well-suited for web frontends that call backend microservices.

Open this question on its own page
05

How does gRPC handle deadlines and timeouts?

gRPC uses deadlines (absolute timestamps) rather than timeouts (durations) to coordinate time limits across distributed calls. When a client sets a deadline, gRPC encodes it in the grpc-timeout metadata header. Every service in the call chain receives this deadline and must respect it — if the deadline passes, the RPC is automatically cancelled with status DEADLINE_EXCEEDED. Setting a deadline in Go: ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second); defer cancel(); resp, err := stub.GetUser(ctx, req). Deadline propagation is a key advantage of gRPC: when Service A calls Service B with a 5-second deadline, Service B knows how much time remains and can cancel its own downstream calls if insufficient time is left. This prevents cascading slow calls from accumulating. Best practice: always set deadlines on client calls.

Open this question on its own page
06

What is gRPC reflection?

gRPC reflection is a service that allows clients to discover the services and methods available on a gRPC server at runtime, without access to the .proto files at development time. This is analogous to Swagger/OpenAPI exploration for REST. The server registers the reflection service: reflection.Register(grpcServer). Clients like grpcurl use reflection to list services (grpcurl -plaintext localhost:50051 list), describe services (grpcurl ... describe MyService), and call methods (grpcurl ... -d '{"id":1}' MyService/GetUser). The Postman gRPC client and BloomRPC GUI tools also use reflection for schema discovery. In production, you may want to disable reflection to avoid exposing your API surface, or restrict it to development environments.

Open this question on its own page
07

How do you version gRPC APIs?

gRPC versioning follows Protobuf's backward compatibility rules and can be approached in multiple ways: (1) Field-based versioning — add new fields with new numbers; old clients ignore unknown fields; old servers ignore new fields. Never remove or change existing field numbers — this breaks wire compatibility; (2) Package versioning — use Protobuf packages like package myapi.v1 and package myapi.v2; maintain separate .proto files per major version; (3) URL versioning — embed version in the service name or server address (v1.api.example.com:443); (4) Non-breaking changes — safe: adding optional fields, adding new services, adding new RPC methods, adding new enum values; (5) Breaking changes — unsafe: removing fields, changing field numbers, changing field types, renaming fields. The Buf CLI provides a buf breaking command to detect breaking changes in CI/CD pipelines.

Open this question on its own page
08

What is the difference between gRPC and GraphQL?

gRPC and GraphQL solve different problems. gRPC is a high-performance RPC framework for service-to-service communication, optimized for internal microservice calls with strict contracts, binary serialization, and streaming. GraphQL is a query language and API protocol for client-to-server communication, allowing clients to request exactly the data they need, reducing over-fetching/under-fetching. Key differences: (1) Data fetching — GraphQL clients specify exactly which fields they want; gRPC returns the full message defined in the proto; (2) Transport — GraphQL runs over HTTP/1.1 with JSON; gRPC uses HTTP/2 with Protobuf; (3) Use case — GraphQL excels for flexible frontend APIs (BFF pattern); gRPC excels for backend microservices; (4) Schema — GraphQL has its own SDL; gRPC uses Protobuf; (5) Streaming — gRPC has native streaming; GraphQL Subscriptions use WebSockets. Many architectures use both: GraphQL for public APIs, gRPC for internal services.

Open this question on its own page
09

How do you test gRPC services?

Testing gRPC services involves multiple levels: (1) Unit testing — test service handler functions directly without a gRPC server: call the handler function with a mock context and request, assert on the response; (2) Integration testing — start an in-process gRPC server on a buffer (bufconn in Go), create a real client, and call methods. No network involved, but tests actual gRPC lifecycle; (3) Contract testing — verify that client and server agree on the Protobuf schema using the Buf registry or Protolock; (4) Manual testing toolsgrpcurl (cURL for gRPC), Postman, BloomRPC, Evans; (5) Mocking — generate mock implementations of service interfaces for dependency injection in tests; (6) Load testingghz (gRPC load testing tool) generates concurrent RPC calls and measures throughput and latency percentiles. Always test streaming methods with multiple messages and cancellation scenarios.

Open this question on its own page
10

What is gRPC health checking?

gRPC health checking is a standardized protocol (grpc.health.v1) that allows load balancers, service meshes, and Kubernetes probes to check whether a gRPC server is ready to handle requests. The health check service provides a Check RPC that returns SERVING, NOT_SERVING, or UNKNOWN for a named service. Implementation in Go: healthServer := health.NewServer(); healthServer.SetServingStatus("", grpchealth.HealthCheckResponse_SERVING); grpc_health_v1.RegisterHealthServer(grpcServer, healthServer). Kubernetes configures gRPC liveness/readiness probes using the grpc probe type (K8s 1.24+): livenessProbe: grpc: { port: 50051 }. The health check can also support watching with the Watch streaming RPC, allowing load balancers to receive real-time status changes and immediately route traffic away from degraded instances.

Open this question on its own page
11

How does gRPC handle load balancing?

gRPC supports load balancing at two levels: (1) Proxy load balancing — a proxy (Envoy, NGINX, Traefik) terminates gRPC connections from clients and distributes them to backend servers. The client doesn't know about individual backends. This is the simplest approach and works well with Kubernetes + Envoy/Istio service mesh; (2) Client-side load balancing — the gRPC client resolves multiple server addresses (via DNS or service discovery) and distributes calls directly. Policies include round-robin (default) and pick-first. Client-side LB eliminates the proxy hop for lower latency. gRPC integrates with DNS-based discovery and xDS (the API used by Envoy) for dynamic configuration. In Kubernetes, since ClusterIP round-robins at the TCP level (not request level), gRPC's long-lived HTTP/2 connections all go to one pod — client-side LB or a service mesh is required for proper per-request load balancing.

Open this question on its own page
12

What is the role of `google.protobuf.Any` type?

google.protobuf.Any is a special Protobuf well-known type that can contain an arbitrary serialized Protobuf message along with its type URL, providing a form of polymorphism in Protobuf's otherwise strongly-typed system. It is defined as: message Any { string type_url = 1; bytes value = 2; }. The type_url identifies the type (type.googleapis.com/mypackage.MyMessage), and value is the serialized message bytes. Use cases: error details in gRPC error responses (attaching structured error info of varying types), extensible event systems where event payloads vary by event type, and plugin architectures where the schema of plugin data is not known to the host. To use: pack with anypb.New(myMessage) and unpack with anypb.UnmarshalTo(anyValue, &targetMsg, proto.UnmarshalOptions{}). Any sacrifices type safety for flexibility — use sparingly and prefer specific types when possible.

Open this question on its own page
13

How do you handle backward compatibility in Protobuf?

Protobuf backward compatibility is maintained through these rules: (1) Never change field numbers — field numbers identify fields in binary encoding; changing them breaks wire compatibility; (2) Never remove fields in use — mark deprecated fields as reserved or leave them in place; (3) New fields are optional by default in proto3 — old clients ignore new fields; (4) Field type changes — some are compatible (int32 → int64), most are not (string → bytes breaks things); (5) Enum values — adding new values is safe; removing values or changing numbers breaks compatibility; (6) Reserve deprecated field numbersreserved 5, 10 to 15; reserved "old_field"; prevents future reuse of those numbers; (7) Use the Buf CLIbuf breaking --against origin/main automatically detects breaking changes in CI. Following Protobuf style guide and semantic versioning for .proto files minimizes compatibility issues in evolving APIs.

Open this question on its own page
14

What is gRPC gateway and what problem does it solve?

grpc-gateway is a plugin for the protoc compiler that generates a reverse proxy HTTP/JSON gateway from annotated .proto files. It solves the browser/REST client compatibility problem: by adding HTTP annotations to your .proto (using google.api.http options), grpc-gateway generates Go code that translates incoming REST/JSON requests to gRPC calls and translates the gRPC responses back to JSON. Example annotation: rpc GetUser(GetUserRequest) returns (User) { option (google.api.http) = { get: "/v1/users/{id}" }; }. This allows you to maintain a single gRPC service definition and expose it as both a gRPC API (for internal microservices) and a REST/JSON API (for browser clients, external partners, or legacy systems) without maintaining two separate server implementations.

Open this question on its own page
15

What is the difference between proto2 and proto3?

Proto3 is the current recommended version. Key differences from proto2: (1) Field presence — proto2 supports optional, required, and repeated; proto3 makes all singular fields optional by default (no required), removing required field validation; (2) Default values — proto3 uses zero values as defaults (0 for numbers, "" for strings, false for bools) and doesn't serialize them, reducing message size; proto2 allows explicit defaults; (3) Unknown fields — proto3 originally discarded unknown fields (fixed in 3.5+ to preserve them); proto2 preserves them; (4) Maps — proto3 has native map fields (map<string, Value>); proto2 uses repeated message entries; (5) JSON mapping — proto3 defines a standard JSON encoding; proto2 doesn't. Proto3 is simpler and preferred for new projects. Proto2 is still used in legacy Google codebases.

Open this question on its own page
16

What are the best practices for designing gRPC APIs at scale?

gRPC API design best practices: (1) Use resource-oriented design — model APIs around resources (nouns) with standard operations (Get, List, Create, Update, Delete, Search), following Google's AIP (API Improvement Proposals) guidelines; (2) Request/response messages per method — even for simple calls, use distinct request/response types (not primitives) to enable future extension without breaking changes; (3) Pagination — use page_size and page_token fields for list operations; (4) Field masks — use google.protobuf.FieldMask for partial updates and sparse reads; (5) Idempotency keys — include a request_id field for Create operations to enable safe retries; (6) Error handling — use rich error details with google.rpc.Status; (7) Deadline-aware — all handlers should check context cancellation regularly; (8) Break detection — use Buf breaking change detection in CI; (9) Document with comments.proto comments generate documentation.

Open this question on its own page
Advanced 10 questions

Deep expertise questions for senior and lead roles.

01

How does gRPC achieve high performance compared to REST?

gRPC's performance advantage over REST comes from multiple compounding factors: (1) Protobuf binary serialization — encodes integers as variable-length bytes, strings as UTF-8, and omits field names (using numbers instead), producing 3–10x smaller payloads than JSON and deserializing 5–100x faster; (2) HTTP/2 multiplexing — multiple concurrent RPCs share one TCP connection, eliminating the connection establishment overhead that HTTP/1.1 incurs per request (TCP handshake + TLS negotiation ≈ 100ms); (3) HTTP/2 header compression (HPACK) — repeated metadata headers (auth tokens, content-type) are compressed to a few bytes after the first request; (4) Binary framing — HTTP/2 frames are parsed in binary, eliminating the string parsing overhead of HTTP/1.1 text format; (5) Connection reuse — channels maintain persistent connections; (6) Native streaming — streaming RPCs avoid the setup overhead of multiple unary calls for sequential data. Benchmarks typically show gRPC throughput 5–10x higher and latency 2–3x lower than equivalent REST/JSON.

Open this question on its own page
02

What is the gRPC Protobuf serialization format and why is it efficient?

Protobuf uses a compact binary encoding based on field numbers and wire types. Each field is encoded as: (field_number << 3) | wire_type followed by the value. Wire types: 0 (varint — integers, bools, enums), 1 (64-bit — double, fixed64), 2 (length-delimited — strings, bytes, embedded messages), 5 (32-bit — float, fixed32). Varint encoding compresses small integers efficiently: numbers 0–127 encode in 1 byte, 128–16383 in 2 bytes — perfect for typical integer values. Fields with default values are omitted entirely — a zero integer is not serialized, dramatically reducing message size for sparse messages. No field names on the wire — only field numbers are encoded, saving bytes and enabling faster parsing. No schema negotiation per message — the schema is compiled into the client/server code. Combined, these choices explain why Protobuf messages are 3–10x smaller than equivalent JSON and 5–100x faster to parse, especially for high-volume, small messages.

Open this question on its own page
03

How do you secure gRPC communication with mTLS?

Mutual TLS (mTLS) requires both client and server to present and validate certificates, providing bidirectional authentication — each side proves its identity cryptographically. Setup: (1) Certificate Authority — create a CA that signs both server and client certificates (cert-manager in Kubernetes, Vault PKI, or manually with OpenSSL); (2) Server configuration (Go): cert, _ := tls.LoadX509KeyPair("server.crt", "server.key"); caCert, _ := ioutil.ReadFile("ca.crt"); caCertPool.AppendCertsFromPEM(caCert); tlsConfig := &tls.Config{ ClientCAs: caCertPool, ClientAuth: tls.RequireAndVerifyClientCert, Certificates: []tls.Certificate{cert} }; (3) Client configuration: similarly loads client certificate and the CA cert to validate the server; (4) Service mesh alternative — Istio and Linkerd automatically inject Envoy sidecars that handle mTLS transparently, without application code changes, using short-lived certificates rotated automatically. mTLS is the foundation of zero-trust service-to-service security.

Open this question on its own page
04

How does gRPC handle service mesh integration (Envoy, Istio)?

gRPC integrates natively with service meshes through the xDS protocol (the API used by Envoy and implemented by Istio/Linkerd control planes). Integration patterns: (1) Sidecar proxy (Envoy) — Istio injects an Envoy proxy alongside each pod. gRPC traffic passes through Envoy, which provides mTLS, circuit breaking, retries, distributed tracing, and observability — no application code changes needed; (2) Proxyless gRPC — gRPC's built-in xDS support allows the gRPC client to directly communicate with the control plane (Istio/Traffic Director) without Envoy, receiving routing, load balancing, and security policies natively. This eliminates the sidecar overhead; (3) gRPC-specific features in Envoy — Envoy understands gRPC semantics: it transcodes between gRPC and JSON/HTTP, understands gRPC health checks, and handles gRPC-level retries (vs. TCP-level retries). The xDS integration enables gRPC to participate fully in service mesh observability and traffic management without being a black box.

Open this question on its own page
05

What are the challenges of debugging gRPC services?

Debugging gRPC services presents unique challenges: (1) Binary format opacity — Protobuf messages are not human-readable; you can't use curl or inspect traffic with text-based tools. Solutions: grpcurl, Postman, Wireshark with proto dissector plugin, enabling gRPC reflection; (2) Distributed context propagation — errors in one service affect upstream callers; without distributed tracing (OpenTelemetry + Jaeger/Zipkin), tracing the root cause across services is difficult; (3) Streaming debugging — streaming RPCs are harder to reproduce and inspect than unary calls; (4) Deadline cascades — tight deadlines can cancel valid calls; enable verbose logging to see deadline values; (5) HTTP/2 connection state — connection issues (GOAWAY frames, RST_STREAM) are harder to observe than HTTP/1.1 connection resets; (6) Proto schema mismatch — when client and server use different .proto versions, proto3's silent field-dropping makes mismatches hard to detect. Solutions: schema registries (Buf Schema Registry), version pinning.

Open this question on its own page
06

How do you implement distributed tracing with gRPC?

Distributed tracing in gRPC uses OpenTelemetry (the standard) to propagate trace context across service boundaries. Implementation: (1) Instrument the gRPC server and client with OpenTelemetry gRPC instrumentation libraries (e.g., go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc); (2) Interceptors — the OTel library provides interceptors that extract/inject trace context from/into gRPC metadata. The server interceptor extracts the traceparent header (W3C format) from incoming metadata and creates a child span; the client interceptor injects the trace context into outgoing metadata; (3) Exporter — send spans to a collector (Jaeger, Zipkin, Tempo) via OTLP protocol; (4) Service mesh tracing — Envoy (Istio) can add tracing headers automatically, but to trace within the application (handler-level spans), OTel instrumentation in application code is needed; (5) Sampling — in production, use tail-based sampling to capture 100% of error traces while sampling successful traces at lower rates.

Open this question on its own page
07

How does gRPC handle multiplexing in HTTP/2?

HTTP/2 multiplexing allows multiple logical streams to share a single TCP connection simultaneously. gRPC maps each RPC call to an HTTP/2 stream identified by a unique stream ID. Multiple concurrent RPCs can be in flight over one connection: Stream 1 carries the GetUser request, Stream 3 carries a ListProducts request, Stream 5 carries a CreateOrder request — all active simultaneously without waiting for each other. This solves HTTP/1.1's head-of-line blocking problem (where a slow response blocks subsequent requests on the same connection). In gRPC's streaming RPCs, the entire duration of the stream — which may be minutes — corresponds to one HTTP/2 stream. Flow control operates per-stream: each stream has its own window that prevents fast producers from overwhelming slow consumers. The HTTP/2 connection-level flow control governs total bandwidth. gRPC exposes MaxConcurrentStreams and InitialWindowSize settings to tune these parameters for high-throughput workloads.

Open this question on its own page
08

What is gRPC-ALTS (Application Layer Transport Security)?

ALTS (Application Layer Transport Security) is Google's internal authentication and encryption protocol, designed as an alternative to TLS for Google Cloud environments. Unlike TLS which operates at the transport layer, ALTS is implemented at the application layer and is tightly integrated with Google's infrastructure for machine identity. Key features: (1) Mutual authentication — both client and server authenticate using workload identity (tied to service accounts); (2) No certificate management — identity is established through the Google Cloud metadata service, eliminating the certificate lifecycle management burden of mTLS; (3) Hardware acceleration — ALTS is optimized for Google's data centers and can leverage hardware encryption offloading; (4) Transparent rekeying — session keys are rotated during long-lived connections; (5) Usage — set up with credentials.NewClientALTSCredentials() in gRPC Go. ALTS is only available within Google Cloud infrastructure; external deployments use TLS/mTLS instead.

Open this question on its own page
09

How do you implement custom gRPC load balancing strategies?

gRPC's load balancing is pluggable via the balancer.Builder interface. Custom load balancers implement: (1) Resolver — discovers backend addresses (from DNS, Consul, etcd, or custom service registry) and updates the balancer with address changes; (2) Balancer — receives address updates and RPC requests, selects a backend connection, and creates the SubConn; (3) Picker — makes the per-RPC selection decision. Built-in strategies: round_robin (distributes evenly), pick_first (uses first available). Custom strategies: least-loaded (track in-flight requests per connection, pick minimum); weighted round-robin (weight backends by capacity); locality-aware (prefer same-zone backends for lower latency); session affinity (route specific users to specific backends for cache warming). The xDS-based load balancing (via Envoy or Traffic Director) provides dynamic policy updates without code deployment, making it the preferred approach for advanced scenarios in Kubernetes environments.

Open this question on its own page
10

What are the best practices for designing gRPC APIs at scale?

Designing gRPC APIs for large-scale production systems: (1) Schema registry — use Buf Schema Registry or Confluent Schema Registry to version and share .proto files across teams; prevent breaking changes with CI enforcement; (2) API versioning strategy — maintain parallel v1/v2 packages; use compatibility shims during migration; (3) Observability — instrument all services with OpenTelemetry; track RPC latency histograms, error rates by status code, and active stream count per service; (4) Deadlines — establish a deadline budget for each API tier (e.g., 100ms for latency-sensitive reads, 5s for mutations); enforce with interceptors; (5) Circuit breaking — configure Envoy or client-side circuit breakers to prevent cascade failures; (6) Graceful shutdown — drain in-flight streams before shutdown with a grace period; (7) Retries with idempotency — only retry idempotent operations; use request IDs to deduplicate; configure retry policies in service mesh rather than client code; (8) Rate limiting — implement per-client quotas via server-side interceptors using Redis sliding windows; (9) Documentation — treat .proto comments as API documentation; generate reference docs with protoc-gen-doc.

Open this question on its own page
Back to All Topics 46 questions total