Skip to content

VPC Networks

VPC Networks allow your Workers to access any service in your private network without pre-registering individual hosts or ports. You can bind to a specific Cloudflare Tunnel to reach any service behind that tunnel, or bind to Cloudflare Mesh to reach any Mesh node, client device, subnet route or hostname route announced through Cloudflare Tunnel or Mesh, or destination reachable through a Cloudflare WAN on-ramp (GRE, IPsec, or CNI).

At runtime, the URL you pass to fetch() determines the destination — any hostname or IP address reachable through the bound Cloudflare Tunnel or through Cloudflare Mesh. This differs from VPC Services, which require you to create a separate binding for each target host and port combination.

Bind to a Cloudflare Tunnel

Reference a specific Cloudflare Tunnel directly by its UUID:

JSONC
{
"vpc_networks": [
{
"binding": "MY_VPC",
"tunnel_id": "550e8400-e29b-41d4-a716-446655440000",
"remote": true
}
]
}

The remote flag must be set to true to enable remote bindings during local development.

Bind to Cloudflare Mesh

Cloudflare Mesh (formerly WARP Connector) connects your services, devices, and Workers through Cloudflare's global network. When you bind a Worker to Cloudflare Mesh using network_id: "cf1:network", your Worker can reach:

  • Any Mesh node or client device in your account
  • Subnet routes and hostname routes announced through Cloudflare Tunnel or Cloudflare Mesh
  • Destinations reachable through Cloudflare WAN on-ramps (GRE, IPsec, and CNI)

All of this without specifying a particular Cloudflare Tunnel UUID.

Use cf1:network when:

  • Your Workers need to reach private services across multiple Cloudflare Tunnels, Mesh nodes, or Cloudflare WAN on-ramps
  • You want to access your entire private network from a Worker without managing individual Cloudflare Tunnel bindings
  • Your private network topology may change (new connections, new nodes, new routes) and you do not want to update Worker configuration each time

Bind to Cloudflare Mesh using network_id: "cf1:network":

JSONC
{
"vpc_networks": [
{
"binding": "MY_VPC",
"network_id": "cf1:network",
"remote": true
}
]
}

Runtime usage

Access any service in your network at runtime:

TypeScript
export default {
async fetch(request: Request, env: Env) {
// Access a service by private IP
const response = await env.MY_VPC.fetch("http://10.0.1.50/data");
// Access another service on a different port
const dbResponse = await env.MY_VPC.fetch("http://10.0.5.42:5432");
return response;
},
};

When a VPC Network cannot establish a connection to your target service, fetch() throws an exception.

VPC Networks vs VPC Services

VPC Networks and VPC Services both connect Workers to private infrastructure, but they make different trade-offs.

  • Use VPC Services when you have a known set of targets and want each binding scoped to a specific host and port.
  • Use VPC Networks when you need broader access — an entire Cloudflare Tunnel or all of Cloudflare Mesh — and want the URL in your fetch() call to control routing at runtime.

The following table summarizes the differences:

FeatureVPC NetworksVPC Services
ScopeA single Cloudflare Tunnel, or Cloudflare Mesh and Cloudflare WAN routesSpecific host + port
Configurationtunnel_id (single Cloudflare Tunnel) or cf1:network (account-wide)service_id
Service registrationNot requiredRequired for each target
Use whenDynamic discovery, network-wide access, reaching services across your accountFixed, cataloged services

Next steps