How to make worker-to-worker calls with RPC
One worker calling another as a typed method call, with the interface shared instead of stubbed.
How to make worker-to-worker calls with RPC
As an application grows on Cloudflare, it tends to become several workers rather than one: a worker per concern, each deployed and scaled on its own. Those workers still need to talk to each other. Base's RPC is how one worker calls another's procedures as typed function calls, with no public URL and no hand-written request format in between. This post is about that private, back-of-house path. If you have read the general RPC post, this is the internal half of it.
Internal visibility is the whole idea
An RPC service declares its visibility, and for worker-to-worker calls you want internal. An internal service is callable from a bound worker but not exposed to the outside world. That is exactly the contract you want between your own workers: the procedure is reachable by the workers you have wired together, and not by the public internet.
Marking a service internal is a deliberate, declared choice. You are saying "this is part of my private API surface." Nothing about it leaks to clients, and you cannot accidentally publish it by forgetting a setting, because the visibility is stated, not inferred.
Calling another worker
The calling worker reaches the other through an injected, typed client. You inject the client for the service you want to call, and then you invoke its procedures as if they were local methods. The arguments and return types are the types the other worker declared, so the boundary between the two workers is checked by the compiler.
This is the payoff of typed RPC between workers: the two workers share the procedure's type, so a change to a procedure in one worker shows up as a type error in the worker that calls it, at build time. The classic distributed-systems failure, where two services drift out of agreement and only find out in production, is caught before deploy.
What you do not have to build
Without RPC, worker-to-worker communication means designing an internal HTTP API: inventing URLs, serializing request bodies, parsing responses, keeping the two sides in sync by hand and by hope. Base's internal RPC removes all of that. The call is a typed method invocation; the framework carries it (over a fetch-style binding between the workers) and you never write the payload format. You wire the workers together, mark the callee internal, inject its client in the caller, and call.
The mental model to keep
Worker-to-worker RPC is your private, typed API between your own workers: mark the callee internal so only bound workers can reach it, inject its typed client in the caller, and call its procedures like local functions. The framework moves the call; the shared types keep the two workers honest. It is how a Base application splits into many workers without splintering into many hand-written internal protocols.