The debate is never "which is faster" alone
Internal microservice debates stall on benchmarks. In practice, boundaries follow team skills, existing gateways, observability maturity, and how often mobile or browser clients call the service. We have seen .NET shops migrate enthusiastically to gRPC, then route public traffic through REST anyway—paying two stacks. This article collects real tradeoff stories so you can decide with eyes open, not slide-deck slogans.
REST when it still wins internally
Story A — Fintech reporting squad. Twelve services, heavy CRUD, JSON logged everywhere in Splunk. They standardized on ASP.NET Core Minimal APIs and OpenAPI. On-call engineers debug with curl and Postman collections checked into git. gRPC would have saved bytes on large batch exports, but training twenty analysts to read protobuf hex dumps was non-starter. Decision: REST internal, gzip where needed, pagination cursors on heavy endpoints.
REST strengths for internal use:
- Universal tooling and human-readable logs (with redaction).
- Easier gradual versioning via headers and URL paths.
- Firewalls and corporate proxies that understand HTTP/1.1 well.
gRPC when teams actually benefited
Story B — IoT ingestion platform. Devices sent high-frequency telemetry. A .NET worker service called an analytics engine millions of times daily. Switching from JSON REST to gRPC with HTTP/2 cut latency p99 roughly thirty-five percent and CPU on serialization. They used contract-first .proto files in a shared repo; CI broke builds on breaking field renames.
gRPC strengths:
- Strong contracts and code generation in C#, Go, Java.
- Streaming: client, server, and bidirectional for live pipelines.
- Smaller payloads and multiplexed connections on HTTP/2.
// ASP.NET Core gRPC service sketch
public class TelemetryService : Telemetry.TelemetryBase
{
public override async Task Ack(
TelemetryBatch request,
IServerStreamWriter<AckReply> responseStream,
ServerCallContext context)
{
await Process(request);
await responseStream.WriteAsync(new AckReply { Ok = true });
}
}
Hybrid pattern that scales organizationally
Story C — EdTech LMS split. Browser-facing BFF stayed REST/JSON for React. Enrollment, grading, and notification services talked gRPC behind the mesh. YARP or an API gateway translated only where third parties required REST. Developers learned one rule: public north-south REST, east-west gRPC for hot paths. Onboarding doc listed which port exposed which protocol—boring but essential.
Where gRPC hurt (honest failures)
Story D — Startup with three devs. They adopted gRPC because Kubernetes tutorials recommended it. Local dev required Envoy or grpc-web proxies for frontend debugging. Incidents took longer because junior devs could not replay requests from browser network tabs. Six months later they reverted internal admin APIs to REST and kept gRPC only for one streaming alert service.
Warning signs gRPC may be premature:
- No platform team to run service mesh, certs rotation, and proto governance.
- Most consumers are browsers without grpc-web investment.
- Team lacks experience with protobuf backward compatibility rules.
Versioning and compatibility reality
REST teams often ship additive JSON fields and pray. gRPC requires discipline: never reuse field numbers, reserve deprecated fields, use optional carefully. Breaking changes need coordinated multi-service deploys or compatibility shims. Tooling like Buf breaking change detection helps; without it, production panics at deserialization.
Observability and debugging
REST fits generic APM HTTP spans. gRPC needs grpc-specific instrumentation (OpenTelemetry .NET supports both). Log correlation must propagate trace context metadata, not assume headers named like traditional HTTP. Runbooks should document grpcurl commands alongside curl.
Security and mTLS
Internal zero-trust often mandates mTLS between services. gRPC on ASP.NET Core supports client certificates; so does REST behind reverse proxies. Pick what your security team already operates—introducing gRPC plus new CA infrastructure doubles migration risk.
AI-generated APIs caution
Teams use LLMs to draft OpenAPI or proto files. Review for PII fields in messages, overly broad RPC surfaces, and missing pagination on list RPCs that become unbounded streams. Generated code is not architecture.
Decision checklist
- Are primary callers servers, not browsers?
- Is payload size or streaming the bottleneck?
- Do you have proto review in CI?
- Can on-call debug without specialized tools?
If three answers are yes, pilot gRPC on one service with metrics compared to REST baseline for four weeks.
.NET implementation tips
Use Grpc.AspNetCore, health checks, and interceptors for logging. Map gRPC deadlines to CancellationToken. For public REST, keep controllers thin—call application services shared with gRPC hosts to avoid duplicated business logic.
gRPC vs REST is an organizational and operational choice dressed as a technical one. Copy Story C's hybrid unless metrics prove you need full gRPC east-west. Measure, document ports, and train on-call—protocol fashion passes, incident nights do not.