Internal services have different needs than public APIs. Typed contracts beat OpenAPI; binary beats JSON; bidi streaming beats SSE. gRPC was built for this. This post is when it earns its cost.
Where gRPC wins internally
- Typed clients across languages. A Python service calls a Go service with full type safety on both sides. Code-gen handles it.
- Streaming: server-streaming, bidi (see gRPC Streaming Patterns ).
- Performance: ~2× lower latency vs REST/JSON for similar payloads, due to binary encoding + HTTP/2 multiplexing.
- Schema enforcement: protobuf is your contract; breaking changes are detected at build via
buf breaking. - mTLS flows naturally through the service mesh.
Where REST still wins internally
- Polyglot teams less invested in typed clients. REST + OpenAPI is universal.
- Curl-debuggable services. JSON is human-readable; binary protobuf isn’t.
- Browser clients without proxies. gRPC needs gRPC-Web or Connect for browsers.
- Tooling outside your codebase (Postman, Insomnia, dashboards) speaks REST.
Performance reality
For a typical service-to-service call:
| Latency | Throughput | |
|---|---|---|
| REST/JSON | ~10–20ms | 10k req/sec/core |
| gRPC | ~5–10ms | 30k req/sec/core |
Real apps narrow the gap (DB dominates). Don’t switch for raw req/sec; switch for typed contracts and streaming.
The cost of gRPC
- Build complexity: protoc, buf, code-gen. New tooling.
- Debugging: tcpdump shows binary noise. grpcurl helps but isn’t curl.
- Tooling gaps: fewer platforms speak gRPC natively.
- Browser support: gRPC-Web or Connect adds a hop.
The 2026 hybrid
Most production systems:
- REST + OpenAPI at the edge (browser, mobile, third-party).
- gRPC between internal services.
- Connect (gRPC-compatible) when you want both surfaces.
See Go + gRPC + Protocol Buffers for the production patterns.
When to pick what
| Scenario | Pick |
|---|---|
| Polyglot internal services (Go + Python + Rust) | gRPC |
| TypeScript monorepo with shared types | tRPC |
| Public API consumed externally | REST + OpenAPI |
| Service-mesh environment with mTLS | gRPC fits naturally |
| Bidi streaming needed | gRPC or Connect |
| Quick experiments / debugging | REST |
For the broader API choice see GraphQL vs tRPC vs gRPC vs REST .
Read this next
- Go + gRPC + Protocol Buffers
- gRPC Streaming Patterns
- GraphQL vs tRPC vs gRPC vs REST
- Cilium and eBPF in Production
If you want a Go + gRPC + Connect bridge template, it’s at rajpoot.dev .
Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .