Call a private Worker over a Service Binding: no URL, no latency

services = [{ binding, service }] lets Worker A call Worker B by fetch() or by RPC methods on a WorkerEntrypoint; B keeps workers_dev = false and no routes.

Workers

· Chapter

30

·

3

min read

The answer. A Service Binding is a direct handle from one Worker to another on the same account. The call never leaves Cloudflare, is not counted as a request, and by default both Workers run on the same thread of the same machine, so the added latency is effectively zero. Two shapes: env.AUTH.fetch(request) when the callee speaks HTTP, or plain method calls when the callee extends WorkerEntrypoint and exposes methods (RPC). The callee stays private by having no workers.dev URL (workers_dev = false), no route and no custom domain; only Workers holding a binding can reach it. This is the correct answer to "how do I call my other Worker", not a public hostname on your own zone.

The pattern.

// caller wrangler.jsonc
{ "services": [{ "binding": "AUTH", "service": "auth-service-production", "entrypoint": "AuthApi" }] }
// callee: auth-service, exports a named entrypoint with RPC methods
import { WorkerEntrypoint } from "cloudflare:workers";
export class AuthApi extends WorkerEntrypoint<Env> {
  async verify(token: string): Promise<{ sub: string } | null> { /* ... */ return null; }
}
export default { fetch: () => new Response("private", { status: 404 }) };

// caller
const who = await env.AUTH.verify(bearer);            // looks local, is an RPC across the binding
if (!who) return new Response("unauthorized", { status: 401 });

Watch out.

  • service must match the deployed Worker name of that environment (name-staging, name-production), not the top-level name.
  • Bodies are read once. Forward request.clone() if you also read it, or the callee gets an empty stream.
  • RPC hides the network. Arguments are serialized (structured clone), stubs are remote, and detaching a method with .bind() calls a remote method named "bind" (see the Workflows entry).

Related: workflows-step-do-is-an-rpc-receiver · worker-fetch-own-zone-error-1042 · custom-domains-vs-routes-who-is-the-origin