How to cap your Cloudflare Workers bill (and what you cannot)
Short answer: no. In the Cloudflare docs I read for this guide, there is no setting that stops a Worker or blocks charges at a dollar amount you choose. Budget alerts come closest, and Cloudflare's billing docs say plainly: "They do not pause or cap usage." What you can do is contain the bill: limit what one invocation can cost, keep abusive traffic away from the Worker, and find out early when usage jumps.
How Workers billing works
The Workers Paid plan has a minimum charge of $5 per month per account. On the Standard usage model you pay for requests and CPU time. Each month includes 10 million requests and 30 million CPU milliseconds. After that, requests cost $0.30 per million and CPU time costs $0.02 per million CPU milliseconds. Wall-clock duration, egress and static asset requests are not billed. Only requests that hit a Worker count, but Workers run before the Cloudflare cache, so a cached response served through your Worker is still a billed request.
For scale, 1 billion requests at 5 ms of CPU each comes to about $297 for requests, $99.40 for CPU and the $5 base, roughly $401 at the published rates.
The bindings your Worker calls are often where a bug multiplies cost. Paid plan rates beyond the included amounts:
- KV: 10 million reads and 1 million writes included, then $0.50 per million reads and $5.00 per million writes, deletes or lists.
- D1: 25 billion rows read and 50 million rows written included, then $0.001 per million rows read and $1.00 per million rows written. You pay per row, so a full table scan on every request adds up.
- R2: $4.50 per million Class A operations, $0.36 per million Class B operations, $0.015 per GB-month. Egress is free.
- Durable Objects: $0.15 per million requests and $12.50 per million GB-s of duration after 1 million requests and 400,000 GB-s. The WebSocket Hibernation API stops duration charges while an idle object hibernates.
- Queues: 1 million operations included, then $0.40 per million.
Threshold billing is not a cap either. When combined usage charges reach a level Cloudflare sets, and you can't change, it issues a mid-cycle invoice and charges your card.
Limits that act as brakes
Per-invocation limits don't cap how many requests arrive, but they cap what each one can cost.
CPU time. On the Paid plan the default is 30,000 ms per request and the maximum is 300,000 ms. The pricing docs recommend a lower limit to prevent runaway bills and denial-of-wallet attacks. Set limits.cpu_ms in your Wrangler file, or use Workers & Pages, your Worker, Settings, CPU Limits. A request over the limit fails with Error 1102 and shows up in analytics with the outcome exceededCpu.
Subrequests. Paid Workers default to 10,000 subrequests per invocation, adjustable up to 10 million. Cloudflare's February 2026 changelog suggests lowering both subrequests and CPU limits to guard against runaway code. The docs I read don't say what error you get at the subrequest limit, so test it on a deployed Worker: these limits are enforced only on Cloudflare's network, not in local development, and only on the Standard usage model.
{
"name": "my-worker",
"workers_dev": false,
"limits": {
"cpu_ms": 50,
"subrequests": 50
}
}
Pick values from your own metrics: check the CPU time quantiles in the dashboard and leave headroom above your normal P99.
Stop abusive traffic before it reaches the Worker
The cheapest request is one that never runs your code. The tools below are zone settings, so serve production from a route or Custom Domain, as Cloudflare recommends, and set "workers_dev": false. If you only disable workers.dev in the dashboard, the next Wrangler deploy turns it back on, and preview URLs stay active either way.
WAF rate limiting rules
Rate limiting rules count requests matching an expression and act once a client goes over the limit. By zone plan:
- Free: 1 rule, counted by IP, 10-second period, 10-second mitigation timeout.
- Pro: 2 rules, periods up to 1 minute, timeouts up to 1 hour.
- Business: 5 rules, periods up to 10 minutes, timeouts up to 1 day.
- Enterprise: up to 100 rules, with more counting options under Advanced Rate Limiting.
Counting is per data center and can lag a few seconds, so some excess requests get through. Point your rule at the most expensive path.
The Workers Rate Limiting binding (ratelimits in Wrangler config) works inside your code instead. The request is already billed by then, but you can refuse it before it touches KV, D1 or a paid API. Periods are 10 or 60 seconds, and counts are eventually consistent per Cloudflare location.
Under Attack mode
Under Attack mode puts a JavaScript challenge in front of visitors. Cloudflare calls it a last resort for layer 7 DDoS attacks. Turn it on from Quick Actions on the zone overview, or scope it to paths with a configuration rule. The docs warn it may affect API traffic, which matters if machines call your Worker. The pages I read list no plan restrictions for it.
Bot Fight Mode and its paid versions
Bot Fight Mode is free and challenges traffic matching known bot patterns across the whole domain. You can't skip it with WAF rules, and it may challenge API or mobile traffic. Super Bot Fight Mode comes with Pro, Business and Enterprise and adds per-category actions and skip rules. Bot Management, which can target specific endpoints, is an Enterprise add-on.
I found no doc that places Worker execution in the WAF phase order, so after adding a rule, check that blocked traffic no longer shows up in your Worker's request count.
Get warned
- Budget alerts. Under Manage Account, Billing, Billable Usage, set a USD threshold and email recipients. They track account-wide usage-based spend, reset each billing period, send email only and are limited to Pay-as-you-go accounts. Since June 2026 Cloudflare creates a $10 alert for eligible accounts without one. Usage is processed once a day for the previous day, so an alert fires the day after you cross the line.
- Usage Based Billing notifications. Under Notifications, Add, set a usage threshold on one product. This needs a Pro plan or higher and emails the billing address.
- HTTP DDoS Attack Alert. All plans. Fires for mitigated HTTP attacks above 100 requests per second.
- Custom Alerts (beta). Run a SQL API query on a schedule, every minute for most datasets, with email, webhook or PagerDuty delivery. The dataset docs I read mention
logs.workersLogsbut no Workers invocation or CPU dataset, so check the catalog first.
Watch usage yourself
The Workers metrics dashboard shows requests, CPU time and invocation statuses. Cloudflare notes the last few minutes of a chart can dip because of aggregation and delivery delay.
For automation, query the GraphQL Analytics API. The workersInvocationsAdaptive dataset under viewer.accounts returns sum.requests, sum.errors, sum.subrequests and CPU quantiles such as cpuTimeP99, grouped by scriptName and datetime. A token with Account Analytics Read is enough, and the default quota is 300 queries per 5 minutes. I found no documented freshness figure for this data. Requests per hour times $0.30 per million gives you a rough request spend rate to alert on.
A checklist
- Set
limits.cpu_msjust above your normal P99 CPU time. - Lower
limits.subrequeststo what one request needs. - Serve from a route or Custom Domain and set
"workers_dev": false. - Add a WAF rate limiting rule on your most expensive path.
- Turn on Bot Fight Mode or Super Bot Fight Mode if your clients tolerate challenges.
- Know where the Under Attack mode toggle is.
- Put the Rate Limiting binding in front of KV, D1 and paid API calls.
- Create budget alerts at two or three dollar amounts.
- Poll
workersInvocationsAdaptiveso you see spikes in minutes, not a day later.
Cloudflare's own spend alerts are account-wide, email only and built on usage processed once a day, so an overnight spike can run for hours before you hear about it. I found no built-in alert on a single Worker's spend rate. CostHex reads Workers usage every minute through the GraphQL Analytics API with a read-only Account Analytics Read token, turns it into dollars per hour, and alerts you in Slack, Discord, Telegram or email with a link to the Worker. It doesn't stop the Worker. The limits above do the containing, and the alert tells you when to act.
Sources
- Workers pricing, Cloudflare Docs
- Workers limits, Cloudflare Docs
- Wrangler configuration: limits, Cloudflare Docs
- Changelog: Workers are no longer limited to 1000 subrequests, Cloudflare Docs
- workers.dev routing, Cloudflare Docs
- WAF rate limiting rules, Cloudflare Docs
- Workers Rate Limiting binding, Cloudflare Docs
- Under Attack mode, Cloudflare Docs
- Security Level, Cloudflare Docs
- Bot Fight Mode, Cloudflare Docs
- Super Bot Fight Mode, Cloudflare Docs
- Budget alerts, Cloudflare Docs
- Changelog: Budget alerts now on by default for Pay-as-you-go accounts, Cloudflare Docs
- Changelog: Billable Usage dashboard and budget alerts, Cloudflare Docs
- Usage-based billing, Cloudflare Docs
- Threshold billing, Cloudflare Docs
- Optimize costs, Cloudflare Docs
- Available notifications, Cloudflare Docs
- SQL API datasets, Cloudflare Docs
- Workers metrics and analytics, Cloudflare Docs
- Querying Workers metrics with GraphQL, Cloudflare Docs
- GraphQL Analytics API token authentication, Cloudflare Docs
- GraphQL Analytics API limits, Cloudflare Docs