Workers Binding API
VPC bindings provide APIs for accessing private services from your Worker. Both VPC Services and VPC Networks expose a fetch() method for HTTP traffic. VPC Networks also expose a connect() method for raw TCP connections. The difference between binding types is in routing scope, not in API surface.
A VPC Service binding routes requests to a specific pre-registered host and port. The VPC Service configuration always determines the connection target, even if a different URL or host is present in the fetch() call.
- The host provided in
fetch()does not control routing. It only populates theHostheader and, when usinghttps, the Server Name Indication (SNI) value. - The port provided in
fetch()is ignored — the port specified in the VPC Service configuration is always used.
A VPC Network binding grants access to any service reachable through the bound Cloudflare Tunnel or through Cloudflare Mesh — including subnet and hostname routes announced through Cloudflare Tunnel or Mesh, and destinations connected through Cloudflare WAN on-ramps (GRE, IPsec, or CNI). The URL passed to fetch() or the address passed to connect() determines the actual destination — hostname or IP address and port.
Makes an HTTP request to the private service through the bound Cloudflare Tunnel or Cloudflare Mesh. Available on both VPC Service and VPC Network bindings.
const response = await env.MY_BINDING.fetch(resource, options);resource(string | URL | Request) — The URL to fetch. Must be an absolute URL including protocol, host, and path (for example,http://internal-api/api/users).options(optional RequestInit) — Standard fetch options including:method— HTTP method (GET, POST, PUT, DELETE, etc.)headers— Request headersbody— Request bodysignal— AbortSignal for request cancellation
Returns a Promise<Response> that resolves to a standard Fetch API Response object ↗.
The following examples apply to both VPC Service and VPC Network bindings.
export default { async fetch(request, env) { const privateRequest = new Request( "http://internal-api.company.local/users", ); const response = await env.MY_BINDING.fetch(privateRequest); const users = await response.json();
return new Response(JSON.stringify(users), { headers: { "Content-Type": "application/json" }, }); },};export default { async fetch(request, env) { const privateRequest = new Request( "http://internal-api.company.local/users", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${env.API_TOKEN}`, }, body: JSON.stringify({ name: "John Doe", email: "john@example.com", }), }, );
const response = await env.MY_BINDING.fetch(privateRequest);
if (!response.ok) { return new Response("Failed to create user", { status: response.status }); }
const user = await response.json(); return new Response(JSON.stringify(user), { headers: { "Content-Type": "application/json" }, }); },};export default { async fetch(request, env) { const privateRequest = new Request("https://10.0.1.50/api/data"); const response = await env.MY_BINDING.fetch(privateRequest);
return response; },};Opens a raw TCP connection to a private destination through the bound Cloudflare Tunnel or Cloudflare Mesh. Available on VPC Network bindings only.
const socket = await env.MY_BINDING.connect(address);address(string | SocketAddress) — The destination to connect to. Pass a string in"host:port"format (for example,"10.0.1.50:6379") or aSocketAddressobject withhostnameandport.
Returns a Promise<Socket> that resolves to a Socket with readable and writable streams. If connect() cannot establish the connection, it throws an exception.
export default { async fetch(request, env) { const socket = await env.MY_BINDING.connect("10.0.1.50:6379");
const writer = socket.writable.getWriter(); await writer.write(new TextEncoder().encode("PING\r\n")); await writer.close();
return new Response(socket.readable); },};export default { async fetch(request, env) { const socket = await env.MY_BINDING.connect({ hostname: "10.0.1.50", port: 6379, });
const writer = socket.writable.getWriter(); await writer.write(new TextEncoder().encode("PING\r\n")); await writer.close();
return new Response(socket.readable); },};To bind a VPC Service or VPC Network in a Worker, your user needs Connectivity Directory Bind (or Connectivity Directory Admin). Binding directly to a Cloudflare Tunnel through a VPC Network binding requires Connectivity Directory Admin. For role definitions, refer to Roles.
- Configure VPC Services
- Configure VPC Networks
- Refer to usage examples