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
Section titled “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
Section titled “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 defaultsname = "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 stgwrangler deploy --env production # deploys prdBindings — where they go
Section titled “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
Section titled “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 productionSee 03 — Secrets & Security Policy for the full policy and the automated scan that enforces it.
Observability — required
Section titled “Observability — required”Every Worker ships with observability enabled. Without this we can’t debug production incidents.
[observability]enabled = truehead_sampling_rate = 1 # 100% during initial rollout; tune down for high-volume WorkersFor 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)
Section titled “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
Section titled “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 READMESize and performance limits — acknowledge them
Section titled “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
Section titled “Forbidden patterns”- Secrets in
[vars]. Pre-commit hook blocks common patterns; the secret-scan script inscripts/preflight-secrets.shis mandatory in CI. workers_dev = trueon production. Exposes*.workers.devURL 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 ashared-kv:<namespace>tag.
Review checklist (paste into PRs)
Section titled “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).