What is a Remote Procedure Call (RPC)?
Learn what RPC is — client/server stubs, marshaling, and failure semantics — with a real example and OS interview questions answered.
Expected Interview Answer
A Remote Procedure Call (RPC) is an IPC mechanism that lets a program invoke a procedure running in a different address space — typically on another machine — using ordinary-looking function-call syntax, while the underlying framework transparently handles marshaling arguments, sending them across the network, and returning the result.
RPC hides distributed communication behind a familiar local-call interface: the caller invokes a client stub that marshals (serializes) the arguments into a message, sends it to the server over a transport like TCP, and blocks waiting for a reply. On the server side, a matching server stub unmarshals the arguments, calls the actual procedure locally, marshals the return value, and sends it back, after which the client stub unmarshals it and returns control to the caller as if the call had been local. Because the call crosses a network, RPC must additionally handle failures that pure local calls never face — lost messages, partial failures, and duplicate delivery — typically via timeouts, retries, and idempotency guarantees (at-least-once, at-most-once, or exactly-once semantics), which is why RPC is never truly transparent despite the illusion. Modern implementations like gRPC layer a schema (protobuf) and HTTP/2 multiplexing on top of these same core ideas: stub generation, marshaling, transport, and failure semantics.
- Lets distributed code be written with familiar function-call syntax
- Encapsulates marshaling and transport details behind generated stubs
- Provides a foundation for microservice-to-microservice communication
- Forces explicit thinking about network failure modes (retries, idempotency)
AI Mentor Explanation
RPC is like a captain on the field calling a specific tactical instruction to the coach in the pavilion via a runner, then waiting for the runner to bring back a decision, all while the captain experiences it as simply 'asking the coach.' The runner (client stub) writes the question down in an agreed shorthand, carries it, the coach’s assistant (server stub) reads it, gets the coach’s answer, and writes the reply back in the same shorthand for the runner to deliver. If the runner gets lost or the message is dropped, the captain has to resend the request and account for the coach possibly never having heard the first one.
Step-by-Step Explanation
Step 1
Client stub call
The caller invokes what looks like a local function; the client stub marshals the arguments into a message.
Step 2
Transport
The message is sent over the network (e.g., TCP/HTTP2) to the server, with timeouts guarding against lost messages.
Step 3
Server-side execution
The server stub unmarshals the arguments, invokes the actual local procedure, and marshals the return value.
Step 4
Reply and unmarshal
The result travels back over the network; the client stub unmarshals it and returns it to the caller as a normal value.
What Interviewer Expects
- Clear explanation of client/server stubs and marshaling/unmarshaling
- Awareness that RPC cannot be fully transparent due to network failure modes
- Knowledge of at-least-once vs at-most-once vs exactly-once delivery semantics
- A modern example such as gRPC and what it adds (schema, multiplexed transport)
Common Mistakes
- Claiming RPC is exactly as reliable as a local function call
- Forgetting to mention marshaling/serialization as an explicit step
- Not knowing what idempotency has to do with retrying a failed RPC
- Confusing RPC with plain raw socket messaging with no stub/schema layer
Best Answer (HR Friendly)
“An RPC lets one program call a function that actually runs on a completely different machine, but makes it feel just like calling a regular function locally. Behind the scenes, the request and its arguments get packaged up, sent over the network, run remotely, and the answer is sent back and unpacked, and because networks can drop messages, the system has to carefully handle retries so nothing accidentally runs twice.”
Code Example
/* Client side: looks like a local call */
int result = rpc_call("add", 3, 4);
/* Client stub: marshal, send, wait, unmarshal */
int rpc_call(const char *proc, int a, int b) {
struct msg req = { .proc = proc, .args = {a, b} };
send_over_network(&req, sizeof(req)); /* marshal + transport */
struct msg reply;
recv_over_network(&reply, sizeof(reply)); /* blocks for response */
return reply.result; /* unmarshal */
}
/* Server stub: unmarshal, dispatch, marshal reply */
void server_loop(void) {
struct msg req;
while (recv_over_network(&req, sizeof(req)) > 0) {
int result = add(req.args[0], req.args[1]); /* real local call */
struct msg reply = { .result = result };
send_over_network(&reply, sizeof(reply));
}
}Follow-up Questions
- What is the difference between at-least-once and at-most-once RPC semantics?
- How does gRPC build on the classic client/server stub model?
- Why can an RPC never be fully transparent compared to a local call?
- What role does an interface definition language (IDL) play in RPC systems?
MCQ Practice
1. What does the client stub in an RPC system primarily do?
The client stub packages the call's arguments into a message, sends it, and later unpacks the returned result for the caller.
2. Why can RPC never be fully transparent compared to a local function call?
Local calls cannot silently fail mid-execution the way network calls can, so RPC must add explicit handling for lost messages and retries.
3. What does “at-most-once” delivery semantics guarantee for an RPC?
At-most-once semantics prioritize avoiding duplicate execution, accepting that a message might be lost rather than resent unconditionally.
Flash Cards
What is RPC? — A mechanism letting a program call a procedure in another address space using local-call syntax.
What do client/server stubs do? — Marshal arguments/results into messages and unmarshal them on the other side.
Why is RPC never fully transparent? — Network failures (lost messages, duplicates, partial failure) have no local-call equivalent.
Name a modern RPC framework. — gRPC — adds protobuf schemas and HTTP/2 multiplexed transport atop the classic stub model.