Skip to content

02 — Wrangler Configuration Standard

This document defines the canonical wrangler.toml layout for every Adventive Worker. The goal is that any engineer can open a wrangler.toml in any of our repos and find the same fields in the same places, with the same meanings.

The commented reference implementation lives in worker-stub/wrangler.toml (GitHub). Clone that file; don't hand-write a new one. This document exists to explain the choices baked into the stub.

Required top-level fields

Every wrangler.toml must set, at the top of the file:

Field Required Notes
name Yes The dev Worker name in our naming convention. Per-env names are overridden under [env.staging] and [env.production].
main Yes Always src/index.ts. The stub enforces this.
compatibility_date Yes Pin to a concrete date. Update it deliberately, not reflexively. Bumping requires passing the full QA gate.
compatibility_flags Where needed Document each flag with a comment explaining why it's enabled.
workers_dev Yes Set to false for anything customer-facing. A *.workers.dev URL bypasses our DNS and WAF.
account_id No (use env var) Prefer CLOUDFLARE_ACCOUNT_ID in the engineer's shell / CI. Never commit account IDs that aren't already public.

Environment structure

Three environments, in this order in the file: dev (the top-level, unnamed config), then [env.staging], then [env.production]. Keep that order everywhere — it makes diffs readable.

# Top of file = dev defaults
name = "adv-svc-example-dev"
main = "src/index.ts"
compatibility_date = "2026-04-01"
workers_dev = false

[env.staging]
name = "adv-svc-example-stg"
route = { pattern = "example-stg.adventive.com/*", zone_name = "adventive.com" }

[env.production]
name = "adv-svc-example-prd"
route = { pattern = "example.adventive.com/*", zone_name = "adventive.com" }

Deploy commands then look like:

wrangler deploy                     # deploys dev (by omission)
wrangler deploy --env staging       # deploys stg
wrangler deploy --env production    # deploys prd

Bindings — where they go

Bindings declared at the top level apply to dev only. Bindings needed in staging or production must be declared again under the corresponding [env.*] section with IDs that point to staging or production resources. This is a Wrangler quirk — not inheriting bindings is deliberate isolation, and our stub includes a blank scaffold so this never gets forgotten.

Binding type Per-env scaffold Why isolation matters
[[kv_namespaces]] Yes Dev must not read/write prod KV.
[[r2_buckets]] Yes Dev must not overwrite prod objects.
[[d1_databases]] Yes Dev must not schema-migrate prod.
[[queues.producers]] / [[queues.consumers]] Yes Dev messages must not land in prod queues.
[[durable_objects.bindings]] Yes DO state is per-env.
[vars] Yes Non-secret config values. Dev may differ from prod deliberately.

vars vs. secrets — never confuse them

[vars] is plaintext in wrangler.toml and committed to git. Everyone who clones the repo can read it. Use [vars] only for:

  • Feature flags with public-safe names (ENABLE_NEW_HEADER = true)
  • Non-secret URLs (UPSTREAM_API_BASE = "https://api.example.com")
  • Log level (LOG_LEVEL = "info")

Secrets (API keys, signing secrets, DB credentials, OAuth client secrets) never go in [vars] or wrangler.toml. They go in Cloudflare's encrypted secret store, set via:

wrangler secret put STRIPE_SECRET_KEY --env production

See 03 — Secrets & Security Policy for the full policy and the automated scan that enforces it.

Observability — required

Every Worker ships with observability enabled. Without this we can't debug production incidents.

[observability]
enabled = true
head_sampling_rate = 1   # 100% during initial rollout; tune down for high-volume Workers

For Workers expected to exceed ~10M requests/month, set head_sampling_rate to a documented value (e.g. 0.1 for 10%) in the per-env block, and note the rationale in a comment.

Tail consumers (for tier-1 services)

Tier-1 services (see 05) pipe logs to a separate tail Worker so we have an audit trail even if the primary Worker is rolled back. Pattern:

[[tail_consumers]]
service = "adv-int-log-tail-prd"
environment = "production"

Triggers — cron Workers

Cron Workers declare triggers inside each [env.*] block so dev cron doesn't run against prod resources:

[env.production.triggers]
crons = ["0 */4 * * *"]   # every 4 hours — document the schedule in the Worker's README

Size and performance limits — acknowledge them

Comment the current Cloudflare limits in the header of every wrangler.toml. They're worth re-reading before every size-affecting PR:

  • Worker script: 1 MB compressed (10 MB on Workers Paid + select enterprise plans)
  • CPU time: 30 s (paid) / 10 ms (free) — design for the lower bound unless you control the plan
  • Subrequests per invocation: 50 (free) / 1000 (paid)

Forbidden patterns

  • Secrets in [vars]. Pre-commit hook blocks common patterns; the secret-scan script in scripts/preflight-secrets.sh is mandatory in CI.
  • workers_dev = true on production. Exposes *.workers.dev URL that bypasses WAF and DNS.
  • Hand-written duplicate env blocks instead of using the stub. Leads to drift; use the stub and diff against it during review.
  • Inline shell-secret interpolation. Do not write KEY = "${SOMETHING}" and rely on shell env. Use Wrangler's secret store.
  • Multiple Workers sharing a single [[kv_namespaces]] binding ID by convention only. If two Workers genuinely share state, make it explicit by documenting the shared namespace in both repos' READMEs and adding a shared-kv:<namespace> tag.

Review checklist (paste into PRs)

Wrangler config review:
- [ ] name matches naming convention, including env suffix
- [ ] main = src/index.ts
- [ ] compatibility_date set and intentional
- [ ] workers_dev = false
- [ ] observability enabled
- [ ] routes set for stg and prd (not dev)
- [ ] bindings duplicated per env, IDs point to correct env resources
- [ ] no secrets in [vars]
- [ ] tail_consumer set if tier-1
- [ ] cron triggers (if any) only under [env.production.triggers] / [env.staging.triggers]

See the live stub: worker-stub/wrangler.toml (GitHub).