ASP.NET Core gRPC Interview Questions for Senior .NET Developers (2026)
From Protobuf Basics to Production Trade-Offs β A Complete Interview Prep Guide

gRPC has become a first-class communication protocol in ASP.NET Core, and senior .NET developers are increasingly expected to understand it at an architectural level β not just know how to scaffold a service. Whether you are preparing for a technical interview, assessing a candidate, or benchmarking your own knowledge, these questions cover the full spectrum from foundational concepts to the nuanced trade-offs that separate senior engineers from mid-level ones.
π Want implementation-ready .NET source code you can drop straight into your project? Join Coding Droplets on Patreon for exclusive tutorials, premium code samples, and early access to new content. π https://www.patreon.com/CodingDroplets
This guide is structured into three tiers β Basic, Intermediate, and Advanced β so you can calibrate your preparation or candidate assessment to the level of seniority you are targeting. Every question comes with a concise, exam-ready answer that reflects how working engineers reason about gRPC in real ASP.NET Core applications.
Basic-Level gRPC Questions
These questions test foundational understanding of gRPC, Protocol Buffers, and how they integrate with ASP.NET Core.
What Is gRPC and How Does It Differ from REST?
gRPC (Google Remote Procedure Call) is a high-performance, contract-first RPC framework that uses Protocol Buffers (Protobuf) as its serialisation format and HTTP/2 as its transport layer. Unlike REST, which uses JSON over HTTP/1.1 and relies on convention, gRPC uses a binary wire format, supports bidirectional streaming, and generates strongly typed client and server code from a .proto schema file. The key differences are: gRPC is faster and more efficient due to binary serialisation; it enforces a typed contract up front; and it supports streaming natively. REST remains easier to consume from browsers and third-party integrations.
What Is a .proto File and Why Is It Central to gRPC?
A .proto file is the service contract written in Protocol Buffers syntax. It defines the service name, available RPCs, request and response message types, and field definitions with types and field numbers. The dotnet-grpc tooling uses the .proto file to auto-generate C# client stubs and service base classes at build time. This makes the contract the single source of truth, eliminating drift between client and server code β a common problem in REST APIs where documentation and implementation can diverge.
What Are the Four gRPC Call Types?
gRPC supports four communication patterns:
- Unary RPC β the client sends one request and receives one response. Equivalent to a traditional method call.
- Server Streaming RPC β the client sends one request; the server streams multiple responses back.
- Client Streaming RPC β the client streams multiple messages; the server sends one response when the stream closes.
- Bidirectional Streaming RPC β both client and server send streams of messages independently and concurrently.
Each pattern is declared in the .proto file using the stream keyword before the request or response type.
How Do You Add gRPC to an ASP.NET Core Application?
You reference the Grpc.AspNetCore NuGet package, add the .proto file to the project (referencing it in the .csproj with <Protobuf Include="..." />), implement a service class that inherits from the generated base class, and register the service in Program.cs using builder.Services.AddGrpc() followed by app.MapGrpcService<YourService>(). You also need Kestrel configured for HTTP/2, either on a dedicated port or using TLS for protocol negotiation.
What Is a gRPC Channel and How Do You Create One?
A GrpcChannel is the long-lived connection used by gRPC clients to communicate with a server. You create it using GrpcChannel.ForAddress("https://localhost:5001") and then pass it to the generated client constructor. Channels manage connection pooling, load balancing, and reconnection internally. In ASP.NET Core applications, best practice is to register the GrpcChannel as a singleton and the generated client as a transient or scoped dependency via builder.Services.AddGrpcClient<YourClient>(), which integrates the client with IHttpClientFactory for proper lifecycle management.
Intermediate-Level gRPC Questions
These questions probe deeper into streaming, authentication, error handling, and integration patterns that are expected at the senior level.
How Does gRPC Handle Authentication and Authorisation in ASP.NET Core?
gRPC in ASP.NET Core integrates directly with the standard ASP.NET Core authentication and authorisation pipeline. You apply the [Authorize] attribute to service classes or individual methods, and ASP.NET Core's middleware handles token validation before the gRPC handler executes. On the client side, credentials are passed via call metadata β typically an Authorization: Bearer <token> header added using CallCredentials or through a custom DelegatingHandler when using AddGrpcClient. For mTLS (mutual TLS), Kestrel can be configured to require and validate client certificates at the transport level, providing an additional authentication layer suited to service-to-service communication.
What Is Deadline Propagation in gRPC and Why Does It Matter?
A gRPC deadline is a client-specified absolute timestamp by which the entire RPC must complete. If the deadline expires, the call is cancelled and both client and server receive a DEADLINE_EXCEEDED status. Deadline propagation refers to the practice of passing the original deadline through a chain of downstream gRPC calls so that every service in a call graph respects the same time budget. Without propagation, a downstream service may continue processing after the upstream client has already timed out and abandoned the request, wasting resources. In .NET, you pass deadlines via CallOptions and propagate them by reading the ServerCallContext.Deadline on the server and passing it to outbound calls.
What Are gRPC Interceptors and When Would You Use Them?
Interceptors are the gRPC equivalent of ASP.NET Core middleware β they wrap the invocation pipeline and execute logic before and after handler execution. They are implemented by extending Interceptor (Grpc.Core.Interceptors) and registered on either the client or server side. Common use cases include logging, distributed tracing, authentication token injection, retry logic, and correlation ID propagation. Server-side interceptors are registered via builder.Services.AddGrpc(options => options.Interceptors.Add<YourInterceptor>()). Client-side interceptors are applied by calling .Intercept(new YourInterceptor()) on the channel.
How Do You Handle Errors in gRPC?
gRPC uses a defined set of status codes (similar to HTTP status codes) to communicate error outcomes. Common codes include OK, CANCELLED, NOT_FOUND, INVALID_ARGUMENT, UNAUTHENTICATED, and INTERNAL. On the server side, you throw an RpcException with the appropriate StatusCode and an optional detail message. You can also attach rich error details using the google.rpc.Status proto extensions (via Google.Protobuf.WellKnownTypes), which allows structured error payloads β analogous to RFC 7807 Problem Details in REST. On the client side, you catch RpcException and inspect its StatusCode and Status.Detail properties to handle failures appropriately.
What Is the Difference Between GrpcChannel.ForAddress and AddGrpcClient in DI?
GrpcChannel.ForAddress is a direct, manual channel factory suitable for console apps or simple scenarios. AddGrpcClient<T>() is the recommended approach for ASP.NET Core applications because it integrates with IHttpClientFactory, respects the handler lifetime managed by the factory, supports named and typed client patterns, and works cleanly with DI scopes. It also enables easy integration with Polly resilience policies, per-client base addresses, and DelegatingHandler chains β for example, injecting auth headers or logging per client type.
How Does gRPC JSON Transcoding Work and When Would You Use It?
gRPC JSON Transcoding (introduced as an official extension in .NET 7) allows a single gRPC service to be consumed as both a gRPC endpoint and a JSON/HTTP REST endpoint simultaneously, without duplicating business logic. You annotate proto methods with google.api.http options specifying the HTTP verb and path, add the Grpc.AspNetCore.HttpApi or the official Microsoft.AspNetCore.Grpc.JsonTranscoding package, and the framework handles routing and serialisation mapping. Use cases include scenarios where you need browser compatibility or third-party REST consumer support but want to keep gRPC for internal service-to-service communication.
Advanced-Level gRPC Questions
These questions target senior architects and lead developers who are expected to reason about production behaviour, scalability constraints, and advanced integration patterns.
How Would You Implement Retry Logic in a gRPC Client?
gRPC for .NET supports two retry mechanisms. The first is automatic retries configured via RetryPolicy in the ServiceConfig passed to GrpcChannel. You specify retryable status codes (e.g., UNAVAILABLE, INTERNAL), maximum attempt count, and backoff parameters. This is simple and sufficient for transient failures. The second is hedging, where the client sends multiple concurrent requests and uses the first successful response, reducing tail latency. For more complex scenarios (circuit breaking, exponential backoff with jitter), Polly is integrated via AddGrpcClient with .AddPolicyHandler(...). The critical decision: use gRPC native retries for transient network errors; use Polly when you need circuit breaking, bulkhead isolation, or fallback behaviour.
How Does gRPC Load Balancing Work in ASP.NET Core and What Are Its Limitations?
gRPC requires HTTP/2, and HTTP/2 is a multiplexed protocol β multiple RPC calls share a single TCP connection. This means traditional layer-4 load balancers (that route per-connection) will direct all gRPC traffic from a client to a single backend once the connection is established. To achieve real request-level load balancing with gRPC, you need one of the following: (1) client-side load balancing using a resolver (DNS or custom) with round-robin or pick-first policy; (2) a layer-7 proxy like Envoy, YARP, or an Ingress controller that understands HTTP/2 and terminates/re-originates connections; or (3) a service mesh (Istio, Linkerd) that handles routing transparently. In practice, most teams route gRPC traffic through a proxy like Envoy in Kubernetes environments and configure client-side ServiceConfig for retry and timeout policies.
What Are the Performance Implications of Protobuf vs System.Text.Json in a High-Throughput API?
Protobuf uses a compact binary format with varint encoding for integers and no field names on the wire (field numbers instead), making it typically 3β10Γ smaller than equivalent JSON payloads and significantly faster to serialise/deserialise. In high-throughput scenarios (tens of thousands of requests per second), this translates to measurable reductions in CPU time and network bandwidth. System.Text.Json in .NET 8+ with source generation narrows the performance gap considerably for simple object graphs, but Protobuf maintains an advantage for deeply nested messages and large payloads. The relevant trade-off for senior engineers: Protobuf wins on raw throughput but requires schema management and a build step; JSON is self-describing and more forgiving of schema evolution, which matters in rapidly changing systems.
How Do You Handle Schema Evolution and Breaking Changes in Protobuf?
Protobuf supports backward and forward compatibility through field number stability. Adding new optional fields with new field numbers is a non-breaking change β older clients ignore unknown fields, and newer clients provide defaults for missing fields. Breaking changes include: removing or renaming a field number that is still in use, changing a field's type incompatibly, or reusing a field number for a different field. Best practices for production: never remove a field number (mark it reserved instead), never reuse field numbers, and treat required fields (proto2) as an anti-pattern. For teams using gRPC in microservices, maintaining a .proto file registry and enforcing a schema compatibility check in CI (using a tool like buf lint and buf breaking) prevents accidental contract violations.
How Would You Design a gRPC Service for a Multi-Tenant SaaS Platform?
Multi-tenancy in gRPC requires tenant identification and isolation at the request level. Tenant identity is typically passed via metadata (headers) β a x-tenant-id entry added by the client and validated by a server interceptor before the handler executes. The interceptor resolves the tenant context and stores it in ServerCallContext.UserState or injects it into a scoped service. Authorisation policies can then enforce tenant-level access control. For connection-level concerns: since gRPC channels are long-lived, ensure clients are not sharing a single channel across tenant contexts without re-establishing tenant credentials. On the server side, IDbContextFactory<T> with per-tenant connection strings (resolved from the tenant context) handles data isolation cleanly.
What Would You Check First If a gRPC Service Works Locally but Fails in Production?
This is a common debugging scenario. The most frequent root causes in order of likelihood:
- Protocol mismatch β production load balancer or proxy does not support HTTP/2 (many classic ALBs only support HTTP/1.1 for gRPC unless explicitly configured for gRPC or HTTP/2).
- TLS configuration β gRPC over HTTP/2 in production requires TLS; misconfigured certificates or missing ALPN negotiation causes silent protocol downgrade.
- Deadline not set β no deadline on the client means the default is no timeout, but proxies (like Nginx or AWS API Gateway) have their own timeout that will terminate the connection mid-stream.
- Max receive message size β default is 4 MB; large payloads silently fail with
RESOURCE_EXHAUSTEDif not configured on both client and server. - Firewall/network policy blocking HTTP/2 β some corporate networks or Kubernetes NetworkPolicy rules do not permit HTTP/2 traffic on the expected port.
Diagnosing these requires checking gRPC status codes in structured logs, reviewing proxy/load balancer logs for connection-level errors, and using OpenTelemetry traces that capture gRPC status and latency end to end.
gRPC in ASP.NET Core: Real-World Patterns
What Is the Recommended Pattern for gRPC in .NET Microservices?
For synchronous service-to-service communication, gRPC is the preferred choice over REST in high-throughput microservices due to its performance and contract enforcement. The recommended pattern: define .proto contracts in a shared NuGet package (or shared library) consumed by both producer and consumer; use AddGrpcClient on the consumer side with Polly policies for retry and circuit breaking; implement server-side interceptors for logging and correlation; deploy behind a service mesh or L7 proxy for load balancing; and use gRPC health checking (Grpc.HealthCheck) for readiness and liveness probes. Asynchronous communication (events, messaging) should still use a message broker (e.g., MassTransit with RabbitMQ or Azure Service Bus) β gRPC does not replace event-driven patterns.
How Do You Test a gRPC Service in ASP.NET Core?
Unit testing gRPC service handlers is straightforward β the generated base class is just a C# class, so you can instantiate the service, mock dependencies, and invoke handler methods directly using a TestServerCallContext (from Grpc.Core.Testing). For integration testing, use WebApplicationFactory<T> and configure GrpcChannel to use the in-process HttpClient via GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions { HttpClient = factory.CreateClient() }). This gives you a full end-to-end gRPC call path through the real ASP.NET Core pipeline, including middleware, DI, and interceptors, without needing a real network socket. For contract testing across service boundaries, consider a consumer-driven contract testing tool like Pact alongside your .proto registry.
β Prefer a one-time tip? Buy us a coffee β every bit helps keep the content coming!
If you want to see how gRPC fits into a full production API β authentication, caching, error handling, and deployment β Chapter 11 of the ASP.NET Core Web API: Zero to Production course covers Clean Architecture and service communication patterns across a real codebase. It's the context that makes individual concepts click.
Frequently Asked Questions
Is gRPC supported in .NET 8 and .NET 10? Yes. gRPC has been a first-class citizen in ASP.NET Core since .NET Core 3.0. In .NET 8 and .NET 10, gRPC continues to receive improvements including enhanced JSON transcoding, improved server reflection, and better integration with the generic host and OpenTelemetry.
Can gRPC be used from a browser directly?
Standard gRPC-over-HTTP/2 cannot be called directly from a browser because browsers do not expose the HTTP/2 framing APIs required. The solution is gRPC-Web, a protocol adaptation that wraps gRPC messages in HTTP/1.1-compatible framing. In ASP.NET Core, app.UseGrpcWeb() and .EnableGrpcWeb() on the endpoint enable browser clients using a gRPC-Web-compatible JavaScript library. Alternatively, gRPC JSON Transcoding exposes gRPC methods as standard HTTP/JSON endpoints for browser and REST consumers.
What is the default maximum message size in gRPC for .NET?
The default maximum receive message size is 4 MB and the default maximum send message size is unlimited (Integer.MaxValue). Both are configurable via GrpcServiceOptions on the server and GrpcChannelOptions on the client. For large file transfers, gRPC streaming is preferred over increasing message size limits β stream the content in chunks rather than sending a single large message.
How does gRPC handle connection management and reconnection?
GrpcChannel manages the underlying HTTP/2 connection pool automatically. When a connection is lost, the channel enters a transient failure state and uses exponential backoff to reconnect. You can configure keepalive pings via SocketsHttpHandler to detect dead connections faster. For long-running streaming calls, connection drops will surface as RpcException with status UNAVAILABLE, and the application must implement retry or reconnect logic for those streams explicitly.
Should gRPC replace REST for all service communication in a .NET application? No. gRPC is optimised for internal service-to-service communication where performance, streaming, and contract enforcement matter. It is not the right choice for public APIs, browser-facing endpoints, or integrations with third-party systems that expect standard HTTP/JSON. The recommended approach is to use gRPC internally (between microservices) and expose a REST or GraphQL faΓ§ade externally. This gives you the performance benefits of gRPC where they matter most without sacrificing the accessibility and debuggability of REST at the boundary.
What is the difference between gRPC and gRPC-Web? gRPC is the full binary-over-HTTP/2 protocol. gRPC-Web is a subset protocol designed to work over HTTP/1.1, enabling browser JavaScript clients to call gRPC services without a proxy. gRPC-Web does not support client streaming or bidirectional streaming β only unary and server streaming calls are supported. For internal service communication in .NET, always use standard gRPC. gRPC-Web is specifically for browser or legacy proxy environments.
How are field numbers used in Protobuf and why can they not be changed?
Each field in a Protobuf message is identified on the wire by its field number, not its name. When a message is serialised, the field number is encoded alongside the value. If you change a field number, existing serialised messages (in transit, in message queues, or in caches) will be misinterpreted by consumers who have the updated schema. Field names can be renamed freely (they are not on the wire), but field numbers are permanent. Removing a field number requires marking it reserved to prevent future accidental reuse.





