---
title: "Deploy Workers"
---

> Documentation Index
> Fetch the complete documentation index at: https://ermahgerd-docs.t-bd7662a5eeb4.workers.ermahgerd.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy Workers

Worker code enters ermahgerd through Wrangler. Ansible owns the fleet, runtime
pool, management services, and HAProxy; it does not install application code.

## Deploy the bundled Worker

```sh
make deploy
```

The richer bundled applications are deployed with `make examples-deploy`. Their
resources and bindings are described in [Example applications](/examples/).

The target deploys `examples/sum/` using the local deployment API. It provides a
short Git-style deployment message automatically. Set `WRANGLER_MESSAGE` when
your build or release system has its own provenance identifier:

```sh
make deploy WRANGLER_MESSAGE=release:2026.10
```

To deploy the same source under another Worker name:

```sh
make deploy WRANGLER_NAME=another-sum
```

## Use Wrangler directly

Configure Wrangler with an organization UUID and an organization read-write
token. The bootstrap organization is available only for local development:

```sh
cd examples
CLOUDFLARE_API_BASE_URL=http://127.0.0.1:9090/client/v4 \
CLOUDFLARE_ACCOUNT_ID=11111111-1111-4111-8111-111111111111 \
CLOUDFLARE_API_TOKEN=local-development-token \
npx wrangler deploy --config sum/wrangler.jsonc --message git:abcdef0
```

Create organization tokens in the console before deploying for another tenant.
The organization UUID is the Wrangler account ID. See
[Organizations and access](/organizations-and-access/).

## Reach a deployed Worker

Each organization receives an immutable DNS-safe namespace. A Worker is routed
at its own tenant subdomain:

```text
https://<worker>.<organization-namespace>.workers.ermahgerd.localhost:8443
```

For the bootstrap tenant, `sum` is available at
`https://sum.t-bd7662a5eeb4.workers.ermahgerd.localhost:8443`. There is no default Worker:
bare `localhost` and `127.0.0.1` do not select application code.

## Versions and rollback

Every upload is stored as an immutable version. The console presents retained
versions and their deployment history; select a version and use its deployment
action to restore it. New ingress requests use the selected immutable route
after HAProxy publishes the change. Requests already executing retain the
version selected when they entered the runtime.

The deployment API validates an upload with `workerd compile --config-only`
before it can become active. Version metadata and artifacts are durable for the
life of the appliance, so a running appliance restores its routes after a
service or VM restart.

## Supported runtime surface

The appliance supports multiple named Workers, ES modules including imported
WebAssembly, compatibility dates and flags, plain-text and JSON bindings,
encrypted Worker secrets, Cron Triggers, ordinary outbound HTTP/HTTPS,
same-organization service bindings, and common R2 bucket binding operations.
See [Object storage](/object-storage/) for the exact storage surface. It does
also support a key-value service through Wrangler's Workers KV binding
contract, [databases](/databases/) through the D1 contract,
[versioned static assets](/static-assets/), and [native image
transformations](/images/). Organization-owned model inference and Vectorize
bindings are described in [AI and vector search](/ai-and-vector-search/).
[Native Durable Objects](/durable-objects/) provide named SQLite-backed state,
RPC, alarms, and WebSockets for Workers that declare Wrangler migrations.
Worker upload requests are bounded at 128 MiB.
It does not provide Cloudflare route resources, gradual traffic splitting, or
preview URLs.

Workers are logical identities with version history. They do not receive a
dedicated process, port, systemd unit, or network namespace.

## Delete a Worker

Use Wrangler to retire a Worker through the same API used for deployment:

```sh
npx wrangler delete my-worker
```

Wrangler refuses deletion when another Worker has a service binding to the
target. Review the dependency and remove that binding first, or use
`--force` when breaking it is intentional. Deletion removes the Worker's route,
code and version history, secrets, schedules, queue-consumer triggers, static
assets, and Durable Object state. Independently provisioned buckets, databases,
key-value namespaces, queues, model providers, and vector indexes are not
deleted merely because the Worker had bindings to them.

The console offers the same operation from the Worker's overview. It requires
typing the Worker name as explicit confirmation.

## Call another Worker

Declare a Wrangler service binding to grant a Worker the narrow capability to
call one named Worker in the same organization. The target resolves to its
active version at call time, so a target deployment does not require callers to
be redeployed. Global `fetch()` and `connect()` can reach public Internet
addresses. Workerd's public-only network capability rejects loopback,
WireGuard, link-local, and other private destinations; internal platform access
remains available only through declared bindings.

The repository includes a runnable example:

```sh
make service-binding-check
```

See [Organizations and access](/organizations-and-access/) for caller identity
and tenant restrictions.

## Configure secrets and schedules

Use normal Wrangler commands for write-only Worker secrets:

```sh
printf '%s' "$PROVIDER_API_KEY" | npx wrangler secret put PROVIDER_API_KEY
npx wrangler secret list
npx wrangler secret delete PROVIDER_API_KEY
```

Secret changes create immutable versions. Ordinary secret commands deploy the
new version immediately; `wrangler versions secret put` creates a version for a
later deployment. Values are encrypted in the control database, omitted from
artifacts and API responses, and made available to application code through
`env.PROVIDER_API_KEY`. Anyone authorized to deploy arbitrary code to that
Worker can read its secrets at runtime.

Declare recurring UTC schedules in `wrangler.jsonc` or `wrangler.toml`:

```json
{
  "triggers": { "crons": ["*/5 * * * *"] }
}
```

`wrangler deploy` replaces the Worker's trigger set after publishing code. A
native coordinator object on the Worker's stable data shard stores the desired
triggers, wakes through a workerd alarm, durably leases due work, and invokes the
active version's `scheduled()` handler through the trusted runtime dispatcher.
Failed deliveries are retried and may be delivered more than once; missed
intervals are advanced rather than replayed as a wake storm after downtime.
Pause or resume a Worker's deliveries in **Compute → Schedules** without changing
its Wrangler configuration. Organization suspension also stops delivery without
deleting triggers. Resuming can deliver one overdue occurrence before advancing
to a future time; it does not replay every missed interval. See
[Schedules](/schedules/) for management and delivery guarantees.

Source: https://ermahgerd-docs.t-bd7662a5eeb4.workers.ermahgerd.io/deploy-workers/index.mdx
