gRPC, RPC, and binary serialization.

One program asks another program, on a different machine, to run a function and hand back the result. The trick is making that call across machines feel almost as simple as a call inside one.

A remote procedure call, or RPC, hides most of the network mechanics behind a normal-looking function. Binary serialization is how the request becomes a compact stream of bytes to send, then becomes structured data again on the far side. We walk the field the way it is built: what RPC is, why compact formats and efficient transports matter for latency and scale, how modern frameworks work, and where it is heading. The source papers and specifications behind each idea are linked, so you can read them yourself.

A call that looks local, but runs somewhere else.

The field name is the remote procedure call. The everyday version: ask another machine to run a function and hand back the answer.

On the calling side, a stub presents a normal-looking function. It marshals the arguments, which means packing them into bytes, sends them across the network, and unmarshals the reply when it returns. The goal is to make a call between two machines feel almost like a call inside one, while staying honest that the network in the middle can be slow, can drop messages, and can fail.

Two pieces do most of the work. First, an interface definition: both sides agree, in writing, on the exact shape of the request and the reply, meaning the method name, the fields, and their types. Second, binary serialization: turning that structured request into a compact stream of bytes, then turning the bytes back into structured data on the other end. Binary formats pack data tightly and parse quickly, which is why they are common when speed and message size matter.

A function call crosses the network
Client callsGetDeal(id: "D-42")
  1. Serialize the request

    Turn the method and fields into a message for transport.

  2. Run the method on the server

    Look up deal D-42 and build a structured response.

  3. Deserialize the response

    Turn the reply back into values the client can use.

Client receivesstage: "Proposal"
value: 48000
Remote procedure calls package a method call into a request and response. The network still introduces delays and failures, so deadlines and error handling remain part of the design.

On an interactive path, every message has a cost.

Total response time is the sum of many small steps. Packing, transmitting, and parsing each message is part of that budget, and the cost multiplies at scale.

Latency

Small steps add up.

On a live, interactive path, response time is the sum of many small steps. Time spent packing, transmitting, and parsing each message is part of that budget. Compact encodings and efficient transports shrink it.

Message size

Smaller moves faster.

Smaller messages move faster and use less bandwidth. Binary formats omit the overhead of field names repeated as text and use tight integer and length encodings, so the same record fits in fewer bytes.

Throughput at scale

Per-message cost multiplies.

When a service handles many calls per second, the cost of each message multiplies. Reusing one connection for many concurrent requests, rather than opening a fresh connection per call, reduces setup overhead. This is one reason HTTP/2 matters as a transport.

Cross-language services

Many languages, one contract.

Real systems are written in several languages. An interface definition plus code generation lets a service defined once be called from many languages with consistent types. This was the explicit goal of Thrift.

Evolving the contract

Add fields without breaking callers.

Fields get added over time. Formats like Protocol Buffers use numbered fields, so new and old code can still read each other's messages. Services upgrade without breaking every caller at once.

The everyday stake

A live call, fresh data, fast.

Picture a sales voice co-pilot on a live call. Small pieces of work fan out to other services, and the rep feels the total time as how fast fresh information shows up in the app. That is the everyday stake of this field.

From a local-looking call to a fast call across the network.

Agree on the shape, pack to bytes, send over the transport, run on the server, send the reply, unpack. Here are the named ideas that make each step work.

  1. 01Define

    Write the service contract.

  2. 02Serialize

    Encode the arguments.

  3. 03Send

    Cross the network.

  4. 04Execute

    Run the authorized procedure.

  5. 05Return

    Decode the result.

The round trip in named stages: agree on the shape, pack to bytes, send, run, send back, unpack.

1The classic RPC mechanism

Define, bind, marshal, send, run, return.

The idea is old and well specified. The Birrell and Nelson paper (1984) sets out the mechanism: define the call structure, bind a client to a server, marshal the arguments, send them over a transport, run the procedure remotely, and return the result.

That same paper names the hard truths that never went away: binding, partial failure, and performance. It is the conceptual root of everything below, and the reason a careful system never pretends the network has disappeared.

A local-looking call crosses a real network
  1. Client stub

    Package the method name and arguments.

  2. Transport

    Send serialized data across the network.

  3. Server handler

    Decode, authorize, and execute the request.

  4. Response

    Serialize the result and return it to the caller.

The stub hides transport details, but latency, partial failure, and retries remain distributed-system concerns.

2Schema-first binary serialization

Write a schema, encode compact bytes.

Protocol Buffers anchors binary serialization on a clear pipeline. Write a schema describing the messages and fields, run a compiler to generate typed code in your language, then at runtime encode the data into a compact byte stream where each field carries a small numeric tag.

The numbered fields are what make compatibility possible: new and old code can read each other's messages, so a contract can grow without a coordinated upgrade. A binary format drops the repeated text of field names and packs the values tightly, which tends to make messages smaller and faster to parse.

Schema-defined fields can use numeric tags

Readable JSON

{"name":"Ada","id":42}

Binary schema

field 1: string name
field 2: integer id
Encode using the schema

Send typed values with compact field identifiers.

This is a conceptual comparison. Actual byte size and parsing cost depend on the format and data.

3One definition, many languages

Generate the clients, servers, and glue.

An interface definition language, or IDL, is the written contract both sides share. Thrift (Slee, Agarwal, Kwiatkowski, 2007) shows the pattern: a single language-neutral definition file generates client and server code for many languages, along with the serialization and the transport glue.

The lasting lesson is to put the cross-cutting, error-prone work, meaning encoding, language bindings, and transport, behind a generated, consistent layer. Write the contract once, and every language gets matching types instead of hand-written, drifting code.

Generate code from one service contract
service Contacts {
  GetContact(ContactId)
    returns (Contact);
}
Go clientPython clientServer interface
Code generation keeps interfaces aligned with the contract. Compatibility still requires careful schema evolution.

4A modern RPC framework

Pair the definition with a streaming transport.

gRPC pairs the interface definition, Protocol Buffers by default, with HTTP/2 as the transport. From one definition it generates client and server code, and it supports four call shapes: a single request with a single reply, server streaming, client streaming, and bidirectional streaming.

Streaming is what lets results flow continuously rather than one request at a time. For a co-pilot helping in the moment, that is the difference between an answer arriving all at once after the call and updates arriving while the conversation is still happening.

Four request and response shapes
Call shapeClient sendsServer sends
UnaryOne messageOne message
Server streamingOne messageA stream
Client streamingA streamOne message
BidirectionalA streamA stream
Streaming changes the interaction pattern. Both sides still need cancellation, flow control, and error handling.

5Why the transport matters

One connection, many concurrent calls.

HTTP/2 (RFC 9113) carries multiple concurrent requests over one connection, an idea called multiplexing. It frames messages in binary and compresses header fields, so repeated metadata costs less on every call.

For a service making many small calls, reusing one connection and avoiding per-call setup is a direct latency and throughput benefit. This is the transport layer underneath gRPC, and the reason the many-small-calls case scales without opening a fresh connection each time.

Several calls can share a connection
Stream 1
GetContact request and response.
Stream 2
WatchUpdates server stream.
Stream 3
UpdateDeal request and response.
Shared transport connection

Independent logical streams reuse an established connection.

Multiplexing avoids a fresh connection per call. Resource limits and transport contention still apply.

6The honest limits of the abstraction

The network is still there.

RPC makes a remote call look local, but the call still crosses a network. Calls can be slow, time out, or partially fail, and a well built system plans for that with timeouts, retries, and deadlines rather than assuming every call returns.

Naming this keeps the picture accurate. The value of the abstraction is that it hides the routine mechanics, not that it removes the network. The Birrell and Nelson paper named partial failure as a hard truth in 1984, and it still is.

A timeout does not prove the action failed
  1. Client sends a write

    The server may execute it.

  2. Response is delayed

    The client reaches its deadline.

  3. Client considers retry

    Use an idempotency key or query the outcome before duplicating an effect.

The caller can time out after the server has committed. Retry policy must account for that uncertainty.

Efficient machine-to-machine communication is raw material for everything built on top.

At the field level: fast, small messages on interactive paths, services that interoperate across languages, continuous streaming results, higher throughput per connection, and contracts that can evolve.

For a sales voice co-pilot, the bridge is at the outcome level. When the systems behind a co-pilot talk to each other efficiently, the help feels immediate and the rep just keeps talking. The harder cases above, latency, scale, and partial failure, are exactly the ones that decide whether fresh data reaches the app while the call is still live.

Fresh information shows up quickly.

Compact encodings and efficient transports keep the per-call cost low, so a co-pilot can surface what the rep needs while the conversation is still happening rather than after it.

The service stays responsive as usage grows.

Reusing connections and keeping messages small is what holds per-call cost down at scale, so the experience does not degrade as more calls run at once.

Results can arrive continuously.

Streaming in either direction means updates flow in over time, not only in one lump after the call. That fits help that lands in the moment.

Contracts can evolve safely.

Numbered fields let new and old code read each other's messages, so a service can grow without breaking every caller. Steady evolution beats a coordinated, all-at-once upgrade.

This explainer covers published research. To see how AI REV Voice helps with sales conversations, explore Prism.

The direction the field is heading.

We describe the direction, not a roadmap of our own.

Streaming first

Live, incremental results as the norm.

Streaming is becoming a first-class call shape, so continuous results are expected rather than an add-on to request-and-reply.

Browser and edge reach

The same contract, closer to the user.

Variants that let web clients speak these protocols directly are maturing, so an efficient contract can extend closer to where the audio and the user are.

Schema as source of truth

One definition drives everything.

The definition file is increasingly the source of truth for code, validation, documentation, and compatibility checks, not only the wire format.

Reliability built in

Deadlines, retries, and tracing by default.

Frameworks fold in deadlines, retries, backpressure, and tracing, so the honest limits of remote calls are handled rather than left to each caller.

Text and binary coexist

Each format where it fits.

Human-readable formats stay common at system edges for debuggability, while binary formats hold the high-traffic internal paths. The field is converging on fit, not on one format winning.

The sources behind this page.

Keep reading.

Sibling explainers in the Research section, on the latency and systems theme.

Talk. Done.

When the systems behind a co-pilot talk to each other this efficiently, the help feels instant and the rep just keeps talking. See it on a real call.

No app required. Just your phone number.