Remote procedure calls
Call a function on another machine as if it were local: a shared interface, generated stubs and a compact encoding.
4 technologies on this page ↓How it works
Both sides share an interface definition (IDL), such as a .proto file, that lists a service’s methods and the types of their arguments and results. A code generator turns it into a client stub and server code for each language. Your code calls the stub like a local function; the stub encodes the arguments, usually in a binary format that tags each field with a number instead of its name, and sends them over a transport. gRPC uses HTTP/2, so many calls share one long-lived connection and either side can stream a sequence of messages. The server side decodes the request, runs your handler and sends back a result or a status code. Because the network can fail or stall, the caller sets a deadline and retries only failures that are safe to repeat. Versions evolve through those field numbers: new fields get new numbers, old numbers are never reused, and old and new code keep understanding each other. Compared with REST and JSON, the contract is a typed method rather than a URL and a verb, and the bytes mean nothing without the schema. Compared with a queue or pub/sub, the caller waits for an answer from a server that has to be up right now.
Phoning a colleague in another office instead of walking over. You ask in an agreed format, wait on the line for the answer, and hang up if it takes too long. If they’re out, you know at once; leaving a note on their desk would be a queue.
Reach for it when
- Calls between your own services, where both sides can share a schema and payload size and latency matter
- Teams in several languages that want one typed contract and generated clients for each
- Streams over one connection: progress updates, telemetry, or messages flowing both ways
- Many concurrent calls between the same services, multiplexed over one long-lived HTTP/2 connection
Think twice when
- Public APIs for unknown clients: plain HTTP and JSON is easier to call, cache and debug, and browsers need gRPC-Web through a proxy or Connect to speak gRPC
- Work that can wait or must survive the receiver being down; put it on a queue
- One event that several services react to; that’s pub/sub, not one call per consumer
- Chatty, fine-grained calls over long distances, where every call pays a full round trip
A real example
checkout calls orders.GetOrder(id: 4812) with a 300 ms deadline. The generated stub encodes the request as 3 bytes of Protocol Buffers (the JSON {"id":4812} is 11), sends it on an HTTP/2 connection it already holds to one of three orders servers, and gets back an Order or a status such as NOT_FOUND. When a server restarts, calls that fail with UNAVAILABLE are retried; when orders is slow, checkout gets DEADLINE_EXCEEDED after 300 ms instead of hanging. Later the team adds string tracking_url = 7; and old clients keep working, skipping the field they don’t know.
Technologies
Specific products, and what each does differently.
Apache ThriftOpen sourceFacebook’s 2007 RPC framework: define types and services in one IDL file, generate clients and servers for over 20 languages, and pick the wire protocol and transport separately.
Cap’n ProtoOpen sourceA binary format laid out like an in-memory struct, so reading needs no parse step, plus an RPC system built on object references and promise pipelining.
gRPCOpen sourceGoogle’s open RPC framework: describe a service in a `.proto` file, generate typed clients and servers, and call them over HTTP/2 with streaming, deadlines and standard status codes.
Protocol BuffersOpen sourceGoogle’s schema-first binary encoding: messages defined in `.proto` files, fields identified by number, code generated for each language. Apache Thrift | Open source | Apache Software Foundation | Apache 2.0 | 2026-10-06 |
Cap’n Proto | Open source | Cloudflare, Inc. | MIT | 2026-10-06 |
gRPC | Open source | The gRPC Authors (CNCF), started at Google | Apache 2.0 since June 2017 (BSD 3-Clause before); the gRPC-Rust preview is MIT | 2026-10-06 |
Protocol Buffers | Open source | Google LLC | BSD 3-Clause (Apache 2.0 until version 2.0.2 in September 2008) | 2026-10-06 |
What each provider calls it
- AWS
- No RPC framework of its own: you run gRPC or Thrift in your services. Application Load Balancer, CloudFront and VPC Lattice can carry gRPC calls over HTTP/2, and ALB health checks can test gRPC status codes
- Google Cloud
- Cloud Run serves gRPC, including streaming over HTTP/2; API Gateway and Cloud Endpoints add auth, quotas and monitoring to gRPC APIs and can translate HTTP/JSON into gRPC; Cloud Service Mesh supports proxyless gRPC
- Azure
- App Service on Linux and Container Apps ingress serve gRPC; Application Gateway for Containers routes it; API Management passes gRPC through in the self-hosted gateway and (in preview) newer classic-tier instances, not the v2 tiers
- Open source & others
- gRPC; Apache Thrift; Cap’n Proto RPC (object references, promise pipelining); Connect (speaks gRPC, gRPC-Web and its own protocol over HTTP/1.1 or HTTP/2); Twirp (Protobuf or JSON over plain HTTP)
In code · python
# orders.proto (the contract both sides compile):
# service Orders { rpc GetOrder(GetOrderRequest) returns (Order); }
# message GetOrderRequest { int64 id = 1; }
# message Order { int64 id = 1; string status = 2; }
import json
import grpc
import orders_pb2, orders_pb2_grpc # python -m grpc_tools.protoc --python_out=. --grpc_python_out=. orders.proto
# Retries are set per method in the channel’s service config
service_config = json.dumps({"methodConfig": [{
"name": [{"service": "shop.Orders"}],
"retryPolicy": {
"maxAttempts": 3,
"initialBackoff": "0.1s",
"maxBackoff": "1s",
"backoffMultiplier": 2,
"retryableStatusCodes": ["UNAVAILABLE"],
},
}]})
channel = grpc.insecure_channel("orders.internal:50051", options=[("grpc.service_config", service_config)])
orders = orders_pb2_grpc.OrdersStub(channel)
try:
# Reads like a local call: the stub encodes, sends over HTTP/2 and waits at most 300 ms
order = orders.GetOrder(orders_pb2.GetOrderRequest(id=4812), timeout=0.3)
print(order.status)
except grpc.RpcError as err:
print(err.code()) # e.g. StatusCode.DEADLINE_EXCEEDEDOften confused with
Where it came from1984–2017
Before RPC, programs that talked over a network had to pack and unpack messages by hand, which at Xerox PARC was work for “a select group of communication experts”. In 1984 Andrew Birrell and Bruce Jay Nelson described the RPC system they built for the Cedar environment: a programmer wrote an interface module, a tool called Lupine generated the stubs, and a remote call looked like a local one. They even chose to give calls no time-out, because local calls have none.
Sun published its RPC protocol, with data encoded in XDR, as RFC 1050 in 1988. CORBA 1.0 followed in 1991 with an interface definition language for distributed objects. Facebook open-sourced Thrift in 2007: one language-neutral file defined types and services, and numbered fields let old and new versions talk. Google had used its own system, Stubby, for over a decade, but it was tied to Google’s infrastructure.
In February 2015 Google open-sourced gRPC, a successor to Stubby built on HTTP/2 and Protocol Buffers. Its stated principles turned away from distributed objects and “the fallacies of ignoring the network”: coarse-grained messages, deadlines, cancellation and streaming. gRPC 1.0 shipped in 2016 and the project joined the CNCF in 2017.
Why it’s built this way
- Stubs generated from an interface definition
- Birrell and Nelson wanted programmers to write only the interface, the caller and the server. Lupine generated the code that packed arguments and dispatched calls, and both sides were type-checked against the same interface.
- Numbered fields instead of whole-program versions
- Sun RPC versioned whole remote programs, so a server ran several versions side by side. Thrift tagged every field and argument with an identifier, so old code could skip fields it didn’t know and staged rollouts didn’t break callers.
- Deadlines and cancellation, not calls that wait forever
- Cedar RPC left out time-outs to feel like a local call. gRPC’s principles say a client may set a timeout and cancellation can cascade down a chain of calls, so servers stop work nobody is waiting for.
- HTTP/2 as the transport
- Stubby predated public standards. gRPC needed a wire protocol that survives common internet infrastructure, and HTTP/2 brought multiplexed streams and flow control over one connection.
Timeline
- 1984
Birrell and Nelson publish “Implementing Remote Procedure Calls”
- 1988
Sun publishes its RPC protocol as RFC 1050
- 1991
CORBA 1.0 defines an IDL for distributed objects
- 2007
Facebook open-sources Thrift in April
- 2015
Google open-sources gRPC, the successor to Stubby, in February
- 2016
gRPC 1.0 is released in August
- 2017
gRPC joins the Cloud Native Computing Foundation in March
- Birrell and Nelson: Implementing Remote Procedure Calls (ACM TOCS, February 1984)
- RFC 1050: RPC, Remote Procedure Call Protocol Specification (Sun Microsystems, April 1988)
- OMG: CORBA history (CORBA 1.0, October 1991)
- Slee, Agarwal and Kwiatkowski: Thrift, scalable cross-language services implementation (Facebook, April 2007)
- Apache Thrift: About (open-sourced April 2007)
- Google Developers Blog: Introducing gRPC, a new open source HTTP/2 RPC framework (February 2015)
- gRPC blog: gRPC motivation and design principles (Stubby, September 2015)
- gRPC blog: gRPC project is now 1.0 (August 2016)
- CNCF blog: Cloud Native Computing Foundation to host gRPC from Google (March 2017)
Sources21
- gRPC docs: Core concepts (service definitions, unary and streaming RPCs)
- gRPC docs: Deadlines (no default deadline, DEADLINE_EXCEEDED)
- gRPC docs: Retry (service config, retryable status codes, backoff)
- gRPC over HTTP/2 protocol specification
- gRPC docs: gRPC-Web basics (browser calls through an Envoy proxy)
- Protocol Buffers docs: Encoding (field numbers and wire types)
- Protocol Buffers docs: Language guide, proto3 (assigning field numbers, updating a message type)
- Connect docs: Introduction (gRPC, gRPC-Web and the Connect protocol)
- Twirp on GitHub (Protobuf or JSON over HTTP 1.1)
- Cap’n Proto: RPC protocol (capabilities, promise pipelining, round trips)
- Elastic Load Balancing docs: Target groups for Application Load Balancers (gRPC protocol version, gRPC health check codes)
- Amazon CloudFront docs: Using gRPC with CloudFront distributions
- Amazon VPC Lattice docs: Target groups (HTTP/2 and gRPC protocol versions)
- Cloud Run docs: Using gRPC
- API Gateway (Google Cloud) docs: gRPC overview
- Cloud Endpoints docs: Endpoints for gRPC (HTTP/JSON transcoding)
- Google Cloud docs: Cloud Service Mesh overview (proxyless gRPC)
- Microsoft Learn: Configure gRPC on App Service
- Microsoft Learn: Ingress in Azure Container Apps (HTTP/2, gRPC)
- Microsoft Learn: gRPC with Application Gateway for Containers
- Microsoft Learn: Import a gRPC API to Azure API Management (gateway support)