
Run Multiple Cloudflare Workers Locally With One Safe Plan
Resolve Wrangler environments, service bindings, and remote resources before starting a multi-Worker stack, then launch it in dependency order.
A multi-Worker repository can be locally healthy while one service binding is disconnected, one named environment silently replaces its top-level bindings, and one D1 or R2 binding reaches a real Cloudflare resource. The hard part is not starting several Wrangler processes. It is knowing which effective stack those processes will create.
The short answer
Inspect the selected environment first. Resolve every Worker name, binding target, local or remote mode, and service dependency. Only then start the processes in dependency order. Workers Doctor packages that sequence into one read-only inspection command and one guarded development command.
npx workers-doctor inspect --env staging
npx workers-doctor graph --env staging
npx workers-doctor dev --env stagingA Wrangler file is not the effective Worker
Cloudflare's Wrangler configuration reference distinguishes top-level configuration from named environments. Several binding collections are non-inheritable, so an env.staging block replaces the corresponding top-level collection instead of extending it. That makes a raw text search misleading: a binding can appear in the file and still be absent from the selected environment.
{
"name": "api",
"services": [{ "binding": "AUTH", "service": "auth" }],
"d1_databases": [{ "binding": "DB", "database_id": "production-id" }],
"env": {
"staging": {
"name": "api-staging",
"services": [{ "binding": "AUTH", "service": "auth-staging" }],
"d1_databases": [{
"binding": "DB",
"database_id": "staging-id",
"remote": true
}]
}
}
}For staging, the effective Worker is api-staging. AUTH targets auth-staging. DB reaches the staging D1 database remotely. The top-level production database is not inherited. A useful plan must show that result, not just list both database IDs.
Remote bindings change the safety boundary
Cloudflare's local development guide says bindings use local simulations by default and can opt into deployed resources with remote: true. Worker code still runs locally, but operations on that binding reach Cloudflare. That can be intentional for a staging bucket or database, but it should never be invisible in the command that starts development.
Workers Doctor reports every effective binding and flags mixed local and remote state. It also checks missing named environments, unresolved local service targets, dependency cycles, conflicting .dev.vars and .env files, and required secret names that are absent locally. Secret values are never included in the report.
Workers Doctor · staging
2 workers · 3 bindings · 1 remote
api-staging
service AUTH → auth-staging local
d1 DB → staging-db remote
auth-staging
kv SESSIONS local
! WD003 Local and remote state are mixedStart services from the graph, not from memory
Cloudflare documents local service binding development with separate Wrangler processes, and also supports multiple -c flags. In a repository with several packages, the practical failure mode is starting the API before its auth or queue consumer dependency and treating the resulting not connected state as an application bug.
The graph command emits Graphviz DOT for architecture work. The dev command computes a topological order, prints every command and port first, stops on configuration errors, then starts dependencies before their consumers. It detects the repository's package manager from its lockfile and does not deploy or mutate Cloudflare resources.
name: Worker stack check
on: [pull_request]
jobs:
doctor:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: loke-dev/workers-doctor@master
with:
environment: staging
strict: trueMake the stack plan reviewable
The same deterministic inspection can run in CI. GitHub output turns diagnostics into annotations, JSON supports internal tooling, and DOT keeps the dependency map portable. Because inspection is offline, the check does not need Cloudflare credentials.
Know what the tool does not prove
Workers Doctor proves what the supported Wrangler configuration resolves to and whether the local stack has structural risks. It does not prove application behavior, database compatibility, or deployed routing. Use integration tests for behavior and keep staging resources separate from production even when a remote binding is convenient.
The package and Action are available in the Workers Doctor repository. Start with inspect, read the effective plan, and only use dev once the local and remote boundary matches what you intended.
Sources and further reading
- Local development · Cloudflare
- Service bindings · Cloudflare
- Wrangler configuration · Cloudflare
- Workers Doctor source and fixtures · GitHub