gRPC is an open-source remote procedure call framework in which services and their methods are defined in a schema, and client and server code is generated from it for each language. Calls run over HTTP/2, which gives multiplexed requests on a single connection, flow control and bidirectional streaming, and messages are encoded with Protocol Buffers, a compact binary format. It addresses the cost of hand-written service clients and loosely defined JSON APIs: the contract becomes the single source of truth, calls are cheap, and deadlines, cancellation and authentication are part of the protocol rather than conventions. Google ran an internal RPC system called Stubby for more than a decade, and in March 2015 decided to build its successor as open source. The first stable release followed in August 2016, and Google donated the project to the CNCF in early 2017, where it was announced on March 2, 2017 as the foundation’s sixth hosted project. It is an Incubating project. Version 1.84 of the Python and Go libraries was released in September 2026.
CNCF daily · Sprint 1, day 4 · Remote Procedure Call
At a glance
| Category | Remote Procedure Call |
| CNCF status | Incubating. Donated by Google; announced as a CNCF project on March 2, 2017 |
| Written in | C core library plus native implementations in Go and Java, with wrappers for other languages |
| License | Apache 2.0 |
| Transport | HTTP/2 with TLS, or plaintext inside trusted networks |
| Interface definition | Protocol Buffers .proto files |
| Call types | Unary, server streaming, client streaming and bidirectional streaming |
| Languages | Official libraries for 11 languages, including C++, Go, Java, Python, C#, Node.js, Ruby, PHP, Kotlin, Dart and Objective-C |
| Latest releases | 1.84.0 (September 2026) for the Python and Go libraries |
Architecture
flowchart TB
PROTO[Service contract<br/>.proto files] -->|protoc or buf generate| GEN[Generated stubs<br/>client and server code]
GEN --> CLIENT[gRPC client<br/>channel and stub]
GEN --> SERVER[gRPC server<br/>service handlers]
CLIENT --> INT1[Client interceptors<br/>auth, retries, tracing]
INT1 --> CH[Channel<br/>name resolver and load balancer]
CH -->|HTTP 2 over TLS| LB[Proxy or mesh<br/>Envoy, Istio, Linkerd]
LB --> INT2[Server interceptors<br/>auth, metrics, logging]
INT2 --> SERVER
SERVER --> HC[Health checking<br/>and reflection]
INT1 --> OBS[Metrics and traces<br/>OpenTelemetry, Prometheus]
INT2 --> OBS
| Component | Responsibility |
|---|---|
| Proto contract | Defines messages and services. It is versioned in Git and is the only description of the API. |
| Code generation | protoc or buf with language plugins produce typed client stubs and server interfaces. |
| Channel | The client connection abstraction. It resolves names, balances across backends and maintains HTTP/2 connections. |
| Interceptors | Middleware on both sides for authentication, logging, metrics, tracing and retries. |
| Status and deadlines | A defined set of status codes, a per-call deadline that propagates through a call chain, and cancellation. |
| Health and reflection | A standard health-checking service for load balancers and probes, and optional server reflection for tools such as grpcurl. |
| Credentials | TLS and mutual TLS channel credentials, plus per-call tokens. |
Design principle. gRPC is contract first. The schema is written before the code, both sides are generated from it, and the wire format is compatible across versions as long as field numbers are never reused. The framework treats deadlines, cancellation and streaming as part of every call, which suits chains of microservices where one slow dependency should not hold resources indefinitely.
Production reference design
A common pattern on EKS, GKE, AKS or on-premises Kubernetes: internal services talk over gRPC, a gateway exposes selected methods outside the cluster, and the schema is linted and checked for breaking changes in CI.
- Define the contract and keep it in a dedicated repository or directory:
syntax = "proto3"; package orders.v1; service OrderService { rpc GetOrder(GetOrderRequest) returns (Order); rpc WatchOrders(WatchOrdersRequest) returns (stream Order); } message GetOrderRequest { string order_id = 1; } message WatchOrdersRequest { string customer_id = 1; } message Order { string order_id = 1; string status = 2; } - Lint and guard compatibility in CI with Buf, then generate code for each language:
buf lint buf breaking --against '.git#branch=main' buf generate - Expose the standard health service in each server and use Kubernetes native gRPC probes, so a pod only receives traffic when it reports serving:
readinessProbe: grpc: { port: 9000 } periodSeconds: 10 livenessProbe: grpc: { port: 9000 } initialDelaySeconds: 10 - Balance requests, not connections. A plain ClusterIP Service balances once per TCP connection, and a gRPC client keeps one long-lived connection, so traffic can concentrate on a few pods. Use client-side balancing against a headless Service, or route through a proxy that understands HTTP/2 such as Envoy, or through a service mesh such as Istio or Linkerd.
- Route external traffic with a gateway that supports gRPC. The Gateway API defines a
GRPCRouteresource, implemented by Envoy Gateway, Istio, Cilium and other controllers. Check the API version against the controller you install:apiVersion: gateway.networking.k8s.io/v1 kind: GRPCRoute metadata: { name: orders, namespace: orders } spec: parentRefs: [{ name: public, namespace: edge }] hostnames: [grpc.example.com] rules: - matches: [{ method: { service: orders.v1.OrderService } }] backendRefs: [{ name: orders-api, port: 9000 }] - Instrument and secure it. Add OpenTelemetry interceptors for traces and metrics, require TLS or mutual TLS, and set a default deadline on every outgoing call.
Typical production uses include internal microservice calls, streaming of events and telemetry, mobile and device back ends, and control planes such as the Kubernetes container runtime interface and etcd client traffic.
Operational considerations
- Always set deadlines. A call without a deadline can wait forever. Propagate the deadline through downstream calls and size timeouts per method.
- Plan load balancing early. Connection-level balancing is the most common surprise. Decide between client-side balancing, a proxy and a mesh before going to production, and test with uneven traffic.
- Manage schema evolution. Never reuse or renumber fields, mark removed fields as reserved, and run
buf breakingon every change so consumers are not broken by an upgrade. - Browsers need a bridge. Browsers cannot speak native gRPC. Use gRPC-Web with a proxy, or a gateway that translates JSON and HTTP to gRPC, for public-facing clients.
- Limit message and connection behaviour. Set maximum message sizes, keepalive settings and connection age limits, so that rolling deployments drain connections and large payloads do not exhaust memory.
Adoption
- The gRPC project’s own adopter pages describe Square, which replaced a custom RPC system with gRPC for multi-platform support and performance, and Netflix, which extended gRPC internally and contributed improvements upstream.
- Cockroach Labs moved from a home-grown RPC system to gRPC and relies on per-stream flow control. Cisco and Juniper Networks use it for model-driven network configuration and telemetry.
- Within the cloud native ecosystem, gRPC carries Kubernetes container runtime interface traffic, the etcd client API, and the control-plane protocols of Envoy (xDS) and other projects.
Alternatives
| Solution | Model | Best suited to |
|---|---|---|
| REST with OpenAPI | JSON over HTTP/1.1 or HTTP/2 | Public APIs, browser clients and broad tooling support |
| ConnectRPC | Protobuf-based RPC that works over HTTP/1.1, HTTP/2 and gRPC | Teams that want the gRPC contract model with browser-friendly calls |
| Apache Thrift | Schema-based RPC with several protocols | Existing Thrift estates and mixed-language services |
| GraphQL | Client-defined queries over a single endpoint | Aggregating many back ends for front-end clients |
| Message brokers (Kafka, NATS) | Asynchronous messaging | Event-driven designs that do not need an immediate response |
Strengths and limitations
| Strengths | Limitations |
|---|---|
| Strongly typed contracts with generated clients and servers | Native gRPC does not run in browsers without a proxy |
| Efficient binary encoding and multiplexed HTTP/2 connections | Binary payloads are harder to inspect than JSON without tooling |
| Streaming in both directions, with flow control | Connection-level balancing needs a proxy, mesh or client-side policy |
| Deadlines, cancellation and status codes built in | Schema discipline is required to avoid breaking consumers |
| Support for many languages and a large ecosystem | Debugging through proxies and meshes needs HTTP/2 aware tools |
Recommendation
Adopt gRPC for internal service-to-service communication and streaming where several languages or many services are involved, and manage the schema with Buf in CI. Put a proxy, mesh or client-side balancer in front of it from the start, set deadlines on every call, and keep REST or ConnectRPC at the public edge where browsers and third parties need simple access.
References: CNCF project page · CNCF: Google contributes gRPC · About gRPC · gRPC documentation · grpcio on PyPI · gRPC on GitHub