Cloudflare Workers
Pathrule2 Rules • 2 Memories • 1 Skill
A Worker is not a small Node server. It runs in a V8 isolate with a CPU-time budget rather than a wall-clock one, it reaches storage and other services through bindings instead of network calls, and module scope is shared by every request that lands on the same isolate. Code written with server habits either fails to deploy, leaks state between requests, or silently exceeds its CPU allowance. This bundle covers bindings and generated types, the isolate rules, the storage decision between KV, D1, Durable Objects, and R2, and the wrangler configuration that keeps a project on the current runtime.
Suggested path map
Pathrule places each piece on the matching path, so your assistant only sees it where it belongs. This is the scoping you get on import; you can adjust it in your workspace.
Rules
2Reach every service through a binding, with generated types/srchighstrictKV, R2, D1, Queues, Durable Objects, and other Workers are accessed through bindings on env, and the Env type is generated from the configuration.
| 1 | A binding is an in-process reference to another resource: no network hop, no credential to manage, no signing. Calling the same resource over its public API is slower, costs more, and adds a secret you did not need. |
| 2 | |
| 3 | - Access resources as `env.MY_KV`, `env.MY_BUCKET`, `env.DB`, `env.MY_QUEUE`, and other Workers through service bindings. Use the REST API only for control-plane work that has no binding. |
| 4 | - Never hand-write the `Env` interface. Generate it (`wrangler types`) from the configuration so a renamed or missing binding is a compile error rather than a runtime `undefined`. |
| 5 | - Pass `env` explicitly through your code instead of reading a module-level copy. It is per-request state, and capturing it in module scope is how a preview binding ends up serving production traffic. |
| 6 | - Keep secrets as secrets (`wrangler secret put`), read them from `env`, and never inline them in source or in the config file. |
| 7 | - Test against real bindings with the Workers test pool, which runs tests inside the runtime rather than in Node, so KV, D1, and Durable Object behaviour is the actual behaviour. |
Memories
2Wrangler configuration keeps the runtime current/rootNew projects use wrangler.jsonc with an explicit compatibility_date, nodejs_compat where needed, per-environment overrides, and observability enabled.
| 1 | The Worker's behaviour is pinned by its configuration, and stale settings are the most common cause of "it works locally but not on deploy". |
| 2 | |
| 3 | - Use `wrangler.jsonc` for new projects (some newer features are JSON-config only) and keep it in the repo as the source of truth for bindings, routes, and limits. |
| 4 | - Set `compatibility_date` explicitly and move it forward deliberately when you have tested the change. It is the runtime's version pin, not a timestamp to ignore. |
| 5 | - Enable `nodejs_compat` when your code or a dependency imports Node built-ins, and prefer web-standard APIs where you have the choice. A missing flag shows up as a module resolution failure at deploy. |
| 6 | - Define environments for staging and production with their own bindings and routes, so a promotion is a deploy of the same code with different resources rather than an edited config. |
| 7 | - Turn on observability and use `wrangler tail` while debugging. Structured logging plus a request id is what makes an edge deployment debuggable at all. |
| 8 | |
| 9 | See /src for the binding and isolate rules this configuration exposes. |
Choosing storage: KV, D1, Durable Objects, R2, Queues/srcKV for read-heavy config with eventual consistency, D1 for relational data, Durable Objects for coordination and strong consistency, R2 for blobs, Queues for async work.
| 1 | Each store has one job, and picking the wrong one is the most expensive mistake in a Workers architecture because it shapes the data model. |
| 2 | |
| 3 | - KV: read constantly, write rarely, and tolerate eventual consistency. Feature flags, configuration, session lookups. Do not use it as a counter or a write-heavy store; writes propagate globally and reads can be briefly stale. |
| 4 | - D1: relational application data with SQL. Great for the long tail of app queries; treat it like a small database (index what you filter, keep queries narrow) and remember reads have regional characteristics. |
| 5 | - Durable Objects: a single addressable instance that serialises access to its own state. This is the only way to get strong consistency and coordination (rate limiters, real-time rooms, per-entity locks, WebSocket hibernation). |
| 6 | - R2: object storage for blobs, with no egress fee to Workers. Stream to and from it rather than loading objects into memory. |
| 7 | - Queues for asynchronous work and buffering, and the Cache API (or cache headers) in front of expensive computed responses. If a value is expensive to compute and identical for many requests, cache it before reaching for a store. |
| 8 | |
| 9 | See /src for the isolate rules and the redis-caching pattern for cache invalidation strategy. |
Skills
1workers-deploy-review/rootPre-deploy checklist for a Cloudflare Worker: bindings, isolate safety, limits, storage choice, and configuration.
| 1 | --- |
| 2 | name: workers-deploy-review |
| 3 | description: Review checklist for Cloudflare Workers changes covering bindings and generated types, isolate safety, CPU and memory limits, storage selection, and wrangler configuration. Run before deploying. |
| 4 | --- |
| 5 | |
| 6 | # Workers deploy review |
| 7 | |
| 8 | ## Bindings |
| 9 | - [ ] Every Cloudflare resource is reached through a binding, not its REST API. |
| 10 | - [ ] `Env` types are generated, not hand-written, and the build fails on a missing binding. |
| 11 | - [ ] Secrets come from `env`; nothing sensitive is in source or config. |
| 12 | - [ ] `env` is passed explicitly, never captured at module scope. |
| 13 | |
| 14 | ## Isolate safety |
| 15 | - [ ] No mutable module-scope state carries request or user data. |
| 16 | - [ ] Independent I/O runs in parallel; nothing sequential without a reason. |
| 17 | - [ ] Bodies are streamed, not buffered, for anything large. |
| 18 | - [ ] Post-response work runs inside `ctx.waitUntil`. |
| 19 | |
| 20 | ## Limits |
| 21 | - [ ] Computation in the request path is bounded and cheap. |
| 22 | - [ ] Script size is within limits after bundling; no accidental large dependency. |
| 23 | - [ ] Subrequest and downstream failures produce a deliberate response. |
| 24 | |
| 25 | ## Storage |
| 26 | - [ ] The store matches the access pattern (KV read-heavy, D1 relational, Durable Object for consistency, R2 for blobs). |
| 27 | - [ ] Nothing write-heavy or counter-like is in KV. |
| 28 | - [ ] Expensive identical responses are cached. |
| 29 | |
| 30 | ## Configuration |
| 31 | - [ ] `wrangler.jsonc` in the repo, `compatibility_date` explicit and current. |
| 32 | - [ ] `nodejs_compat` set if Node built-ins are used. |
| 33 | - [ ] Staging and production environments have their own bindings and routes. |
| 34 | - [ ] Observability enabled; logs carry a request id. |
Why this pattern
AI agents write Workers like Node servers: REST calls to services that have bindings, hand-written Env interfaces, mutable module-scope state shared across requests, and whole responses buffered in memory.
Built for Teams building APIs and edge logic on Cloudflare Workers.
Keeps your assistant from:
- Calling a Cloudflare service over its REST API when a binding is available
- Hand-writing the Env interface so it drifts from the actual configuration
- Keeping request state in a module-scope variable that the next request reads
- Buffering a large response in memory instead of streaming it
- License
- Apache-2.0
- Version
- 1.0.0
- Updated
- 2026-08-24