Service Bindings Between Deployments

A worker can now call another project in your organization through a service binding declared in ploy.yaml. The call is routed inside the platform, with no DNS lookup, no TLS handshake and no trip over the public internet, and it shows up in the target's request logs marked as internal.

Ploy logo on a dark background

Splitting an app into a frontend, an API and a few backend services meant every call between them went out over the public internet: a DNS lookup, a TLS handshake and a round trip through the edge, just to reach a project your own organization runs. Service bindings now let one deployment call another directly, routed inside the platform.

Declare the binding

Add a service block to the calling project's ploy.yaml, naming the project to call:

kind: dynamic
build: pnpm build
out: dist
service:
API: api

Then call it from your worker. Relative URLs resolve against the target deployment:

export default {
async fetch(request, env) {
const response = await env.API.fetch("/users");
return Response.json({ users: await response.json() });
},
};

ploy types generates a ServiceBinding type for each binding.

How it behaves

Option Behavior
API: api Calls the production deployment of api
API: { project: api, branch } Calls the latest deployment of that branch
New deployment of the target Picked up automatically, usually within two minutes
Chained bindings (A → B → C) Allowed; after eight hops Ploy answers 508 Loop Detected
ploy dev Points the binding at a local server with PLOY_SERVICE_API_URL

Scoped to your organization

  • A binding can only reach a project your organization owns. A deploy that names a project outside it fails, and if a target later leaves your organization, calls through the binding answer 503.
  • Nothing is reachable implicitly: the calling project has to declare the binding.
  • Only production deploys change a project's bindings, so a branch push cannot retarget production's calls.
  • The calling worker cannot pick which deployment answers. Ploy fixes the target when the worker loads and strips any deployment pin the caller sends.

Visible in your request logs

A request that arrived through a binding is logged on the target deployment like any other request, marked Internal with the name of the project that called it. You can tell traffic from your own services apart from traffic from the internet at a glance.

Service bindings are available on every plan, including self-hosted instances.


Service bindings docs → | Try Ploy free →