From Script to Service: A New Way to Compose Workers
Cloudflare Workers started with the simple script — a few lines of code to rewrite a request, adjust a header, or patch a site. But an application built on Workers needs more than a single script. Extensions like KV, Durable Objects, and the upcoming R2 object storage cover distributed data. What was still missing was a clean way to structure an application as a set of collaborating parts — an authentication service that other services call, for instance, with a safe path to test changes before they hit production.
That gap is now closed with the introduction of Services. A service is the new deployment unit for Workers, and unlike a script, it is composable and environment-aware.
Environments for Safer Deploys
Every service includes a production environment and can spin up dozens of preview environments. You can override just about anything per environment — code, environment variables, and even a KV namespace — and switch between them from the dashboard.
Each environment is automatically assigned a unique hostname the moment you create or rename it. DNS records, SSL certificates, and everything else needed to reach it are ready within seconds, with no manual provisioning. For more control, you can attach custom routes from your own domain to an environment.
Promoting code is straightforward: you can move a version from a preview environment to production without rebuilding or re-uploading. Environment settings are stored separately from code, so variable changes don’t need to be repeated or manually aligned during promotion.
Versioned and Auditable Changes
Every modification to a service — a code push or an environment variable update — increments that environment’s version number and gets logged. If something breaks, rolling back is quick, and you can trace exactly what changed and when. Version history also accepts custom metadata, such as a git commit hash or deployment tag, to keep your deployments aligned with your source control workflow.

Service Bindings: Composition Without the Network
Services can call each other directly through a new API called service bindings. A binding lets one service send HTTP requests to another, but those requests never touch the public Internet — or any network at all.

In practice, this means one Worker can invoke another Worker from code. For example, your API service can route requests through a separate authentication service for validation before proceeding.
export default {
async fetch(request, environment) {
const response = await environment.AUTH.fetch(request);
if (response.status !== 200) {
return response;
}
return new Response("Authenticated!");
}
}
Because service bindings use the standard fetch API, your existing utilities and libraries continue to work. Bindings also support environment targeting, which opens up canary testing: route a small percentage of traffic to a preview version of a service, and fall back to production if that version errors.

export default {
canRetry(request) {
return request.method === "GET" || request.method === "HEAD";
},
async fetch(request, environment) {
if (Math.random() < 0.01) {
const response = await environment.CANARY.fetch(request.clone());
if (response.status < 500 || !canRetry(request)) {
return response;
}
}
return environment.PRODUCTION.fetch(request);
}
}
This isn’t a microservice architecture in the usual sense. When you deploy a service, Cloudflare analyzes its bindings and builds a dependency graph, packaging all dependent services into a single deployment. Calls between bound services execute immediately — there’s no network hop, no added latency, and no risk of network failures between services.

The benefit of this zero-cost abstraction is that teams can compose and share services freely. The mental overhead of orchestration — YAML templates, backoff logic, and service discovery — is removed; you just write code against fetch and the platform stitches it together.
Availability Today
Services are available now. Existing Worker scripts have already been migrated automatically: each script is now a service with a single "production" environment, and no action is required on your part. The dashboard and existing Cloudflare APIs continue to work as before.
Creating and deploying code to multiple preview environments is part of the open-beta launch. Service bindings and version history are still in progress; access to bindings is being rolled out through an early-access program. You can start building with services immediately at the Workers dashboard, and sign up for early access to service bindings.



