· cloudflare-workers / pricing / serverless

The real cost of running production on Cloudflare Workers

Workers is cheap for I/O-heavy APIs at high request volume. KV writes, D1 write bugs, and unhibernated Durable Objects are where bills go sideways.

By

2,984 words · 15 min read

Cloudflare Workers is genuinely cheap for certain workloads — and surprisingly expensive for others. The headline is $5/month for 10 million requests. The actual bill for a KV-write-heavy side project can hit $158/month. Two D1 runaway-write bugs hit one production developer with a $4,586 charge in a single billing cycle. This article shows the math, the traps, and the workloads where Workers wins or loses on cost.

Who this is for

Backend developers evaluating Cloudflare Workers for production — or already running on Workers and trying to understand why the bill is higher than expected. If you’re deciding between Workers, AWS Lambda, and Vercel for a new project, the comparison table will help you model costs before you commit. For a hands-on look at the runtime itself, the Cloudflare Workers review covers developer experience, limits, and the full feature set.

How Cloudflare Workers billing actually works

Workers switched to CPU-time billing in October 2023. You pay for the time your code is executing, not the total wall-clock duration of the request. If your Worker spends 100ms waiting for a D1 query and 5ms actually running JavaScript, you’re billed for 5ms of CPU time — not 105ms.

This is why I/O-heavy workloads are dramatically cheaper on Workers than on Lambda. Lambda billed on wall-clock from the start, so if your function spends 90% of its time waiting on DynamoDB, you pay for all of it. Workers does not. For a backend that’s mostly database reads and external API calls — which is most backends — this difference is real money.

Five meters make up a Workers bill:

MeterWhat it covers
RequestsEvery HTTP request that hits a Worker
CPU timeCode execution time, in milliseconds
KV operationsRead and write operations to Workers KV
D1 operationsRead and write operations to D1 SQLite databases
Durable ObjectsRequests to and duration of Durable Object instances

R2 object storage has its own billing outside this table, covered in the gotchas section.

Free tier and Paid plan limits

The Workers free tier is limited to 100,000 requests/day and has no SLA. For production, you need the Paid plan at $5/month. That $5 includes:

MeterIncluded in Paid plan
Requests10M/month
CPU time30M CPU-milliseconds/month
KV reads10M/month
KV writes1M/month
D1 reads25B rows/month
D1 writes50M rows/month
D1 storage5 GB
Durable Objects requests1M/month
Durable Objects duration400,000 GB-sec/month
R2 storage10 GB/month
R2 Class B ops (reads)10M/month

Beyond these limits, overage rates apply:

MeterOverage rate
Requests$0.30/million
CPU time$0.02/million CPU-ms
KV reads$0.50/million
KV writes$5.00/million
D1 reads$0.001/million
D1 writes$1.00/million
R2 storage$0.015/GB-month
R2 Class A ops (writes, deletes, list)$4.50/million
Durable Objects requests$0.15/million
Durable Objects duration$12.50/million GB-seconds
DO SQLite storage (since Jan 7, 2026)$0.20/GB-month
Log events$0.60/million

The KV write rate — $5.00/million, 10× the read rate — is where most budget surprises live. Keep that number in mind as you read the scenarios below.

Three scenarios with line-item math

Scenario 1: solo side project, KV-heavy session storage

A developer tools side project receiving 5 million requests per day (150M/month), using KV to store session data. Each request triggers one KV read and one KV write.

Line itemVolumeRateCost
Base plan$5.00
Requests (150M – 10M included)140M$0.30/M$42.00
KV reads (150M – 10M included)140M$0.50/M$70.00
KV writes (150M – 1M included)149M$5.00/M$745.00
CPU time (est. 3ms avg per request)450M CPU-ms – 30M included = 420M$0.02/M$8.40
Total~$870/month

That number looks alarming. It is. But notice that the KV write volume (150M/month from 5M req/day) is the specific driver. If you’re writing to KV once per session creation rather than once per request — and caching the session data in-memory for the lifetime of the Worker instance — the write volume drops 100× or more.

A more realistic version of the same project, with sessions created at login and read on each subsequent request:

Line itemVolumeRateCost
Base plan$5.00
Requests (150M – 10M included)140M$0.30/M$42.00
KV reads (150M – 10M included)140M$0.50/M$70.00
KV writes (est. 1M new sessions/month)0 overage$0.00
CPU time (est. 3ms avg)420M overage$0.02/M$8.40
Total~$125/month

Still not $5. At 150M requests/month you’re a legitimate mid-traffic app, and request overage alone is $42. But the difference between $870 and $125 is entirely write pattern — not request volume.

The Researcher’s original dossier cited ~$158/month for this scenario with partially optimized writes. That math checks out.

Scenario 2: SaaS backend, D1 + modest Durable Objects

An API backend for a subscription SaaS: 10M requests/month, each doing approximately 2 D1 reads and 0.1 D1 writes on average (reads dominate), plus 500K Durable Object requests for session management with low average hold time.

Line itemVolumeRateCost
Base plan$5.00
Requests10M included$0.00
D1 reads (20M rows – within 25B/month included)0$0.00
D1 writes (1M rows – within 50M/month included)0$0.00
DO requests (500K – within 1M/month included)0$0.00
DO duration (~3,125 GB-sec – within 400K GB-sec/month included)0$0.00
CPU time (est. 15ms avg)150M CPU-ms – 30M included = 120M$0.02/M$2.40
Total~$7.40/month

This is where Workers shines. A SaaS backend at 10M requests/month with a real database runs under $10/month if the write patterns are sane. The included limits do a lot of work at this scale — 25 billion D1 reads and 50 million D1 writes per month cover normal workloads entirely. The cost trap with D1 is not routine usage; it’s the lack of a hard billing cap when a bug causes runaway writes. The same workload on AWS Lambda plus API Gateway runs $38–45/month.

Scenario 3: compute-heavy image processing

Image resizing or transformation: 1M requests/month, each using ~80ms of actual CPU time.

Line itemVolumeRateCost
Base plan$5.00
Requests1M included$0.00
CPU time (80M – 30M included)50M CPU-ms$0.02/M$1.00
Total~$6/month

Workers is still cheap at low volume. Scale it to 10M requests/month at 80ms CPU each:

Line itemVolumeRateCost
Base plan$5.00
Requests (10M – 10M included)0 overage$0.00
CPU time (800M – 30M included)770M CPU-ms$0.02/M$15.40
Total~$20/month

Still cheaper than Lambda at this scale. But Workers caps memory at 128MB, which limits the complexity of in-memory image processing. For large file transforms, you’ll likely hit the 128MB ceiling before the billing becomes a concern.

Platform comparison at 10M requests/month

Fixed workload: 10M requests/month, 15ms average CPU time, read-dominant pattern.

PlatformMonthly costKey difference
Cloudflare Workers~$5Base plan covers this workload entirely
AWS Lambda + API Gateway~$38Wall-clock billing + per-call API GW fee
Vercel Pro$20/user/month + computePer-user pricing; compute beyond generous limits

Lambda beats Workers when individual invocations average more than ~100ms CPU at high request volume. Above that threshold, Lambda’s ability to allocate up to 3,008MB of memory (and proportionally more CPU) changes the math. Workers is capped at 128MB and bills per CPU-ms — there’s no way to buy a faster instance.

For I/O-heavy workloads under the 128MB ceiling, Workers wins. For compute-heavy workloads at large memory requirements, Lambda is more flexible.

For a detailed head-to-head on latency, ecosystem, and cold starts, see the Cloudflare Workers vs AWS Lambda comparison.

Five hidden cost traps

1. D1 has no hard billing cap — the $4,586 disaster

In January 2026, a developer faced a Cloudflare bill of $4,586.64 from two separate D1 runaway incidents. In the first (Jan 11–14), a heritage-records worker missing deduplication wrote 3.45 billion rows over four days. In the second (Jan 1–4), a GitHub data harvester missing conflict handling inserted 910 million rows — a combined ~4.83 billion rows with no platform protection. D1 has no hard billing cap — no circuit breaker in the platform itself.

Cloudflare eventually waived the full amount, but it took 18 days. The full postmortem is at littlebearapps.com/blog/d1-billing-disaster-circuit-breakers/.

The failure mode here isn’t unique to D1 — any metered service can produce a runaway bill from a loop bug. D1’s low per-read cost ($0.001/M) makes it feel cheap; the write cost ($1.00/M, 1,000× higher than reads) is what actually kills you.

Three things to do before you ship any cron job or scheduled Worker against D1:

// Rate limit D1 writes via a KV counter
const key = `d1-write-counter:${new Date().toISOString().slice(0, 10)}`; // YYYY-MM-DD
const count = parseInt(await env.RATE_LIMIT.get(key) ?? '0', 10);
const DAILY_WRITE_LIMIT = 1_000_000; // tune to your expected max

if (count >= DAILY_WRITE_LIMIT) {
  throw new Error(`D1 daily write limit reached: ${count}`);
}

await env.RATE_LIMIT.put(key, String(count + 1), { expirationTtl: 86400 });
// safe to proceed with D1 write

Also: set a Cloudflare billing alert at a dollar threshold you’d actually notice — before the code ships. The platform has this; most people don’t configure it.

For a deeper look at D1’s feature set, query limits, and SQLite compatibility, see the Cloudflare D1 review.

2. KV write asymmetry: 10× more than reads

KV reads cost $0.50/million. KV writes cost $5.00/million. The asymmetry exists because KV writes are globally replicated across Cloudflare’s network — the write cost reflects real infrastructure.

Patterns that hit this without warning:

  • Writing session state on every authenticated request (auth token refresh, user presence updates)
  • Using KV as a simple counter or analytics accumulator
  • Storing per-request metadata for debugging

The pattern to replace most write-heavy KV use cases: write to KV only on explicit state change (login, logout, preference update). Cache in memory within the Worker instance for the duration of its lifecycle. Workers Analytics Engine is the right tool for event/metrics data — different billing model, built for append-heavy workloads.

3. Durable Objects without Hibernation API: idle WebSocket charges

Durable Objects bill on wall-clock duration: $12.50 per million GB-seconds. A Durable Object stays “alive” — and billing — as long as any WebSocket connection keeps it active.

Consider 1,000 persistent WebSocket connections, each holding a DO instance open for 24 hours:

1,000 DOs × 86,400 seconds × (128MB / 1,024) GB
= 1,000 × 86,400 × 0.125
= 10,800,000 GB-seconds/day
× 30 days = 324,000,000 GB-seconds/month
÷ 1,000,000 × $12.50 = $4,050/month

The Hibernation API suspends a DO when all its WebSocket connections go idle, resuming only on an incoming message. With hibernation, the billing flips from wall-clock to event-driven — you pay only for the brief CPU burst that handles each message, not for sitting idle between them.

At 1,000 connections with typical 1 message/second traffic:

1,000 DOs × 1,000 messages/day × 5ms CPU/message
= 5,000,000 CPU-ms/day = 150,000,000 CPU-ms/month
= 150M CPU-ms – 30M included = 120M overage
120M × $0.02/M CPU-ms = $2.40/month

That’s the difference between $4,050 and $2.40. The Hibernation API is not optional for production WebSocket servers. Liveblocks handles 500 million WebSocket messages/day on Workers using exactly this pattern.

4. Logging amplification: $0.60/million log events

Workers logging (Logpush, Console API) costs $0.60 per million log events. At verbose logging — 100 events per request, 10M requests/month — that’s 1 billion log events = $600/month in logging alone.

This is easy to overlook during development, where you never hit volume. Verbose request/response logging that costs nothing at 10,000 requests/day costs $600/month at 10M requests/month.

The standard fix: structured logging with sampling. In production, log errors and slow requests unconditionally; sample everything else at 1%. A 1% sample on info-level logs at 10M requests/month = 100K sampled events/month, well inside the included limit.

5. R2 Class A operations: zero egress ≠ zero cost

R2’s headline differentiator is zero egress fees — no charges for data leaving Cloudflare to your users. This is real and meaningful. S3 egress at scale is a significant bill; R2 eliminates it entirely.

But R2 still charges for Class A operations: writes, deletes, and list operations at $4.50/million. Serving a read-heavy CDN — a static asset store, an image library — is effectively free beyond storage. But write-heavy use cases pay for every object ingested.

10M object uploads/month = $45 in Class A ops. That’s actually cheaper than S3 PUT requests at $0.005/1000 ($50/M), but the “zero egress” framing can create a mental model where R2 is universally free. It’s free to serve; it’s not free to write.

For log archiving, event capture, or any pattern that uploads frequently, factor in Class A ops before assuming R2 is cost-free.

Real production at scale

Baselime: 83% cost reduction from AWS to Cloudflare

Baselime is an observability SaaS that moved its full infrastructure from AWS to Cloudflare in 2023. Total daily cloud cost dropped from $1,940 to $325 — an 83% reduction. Their workload is I/O-heavy: ingesting log lines, tracing spans, querying across customer event datasets. Exactly the workload where Workers’ CPU-time billing helps most. They were paying Lambda for wall-clock time on a workload that was 80%+ waiting on I/O.

Source: blog.cloudflare.com/80-percent-lower-cloud-cost-how-baselime-moved-from-aws-to-cloudflare/

Liveblocks: 500M WebSocket messages/day

Liveblocks runs collaborative editing infrastructure — multiplayer cursors, shared state, presence — on Workers with Durable Objects. At 500 million WebSocket messages/day, Durable Objects with the Hibernation API is the architecture. Without hibernation, the wall-clock DO duration cost would be unworkable at that message volume. This is the largest published Workers production deployment I’m aware of, and it’s built on the exact pattern (DO + hibernation) that the billing section above shows is essential.

Source: cloudflare.com/case-studies/liveblocks/

Verdict

Workers is the right call when:

  • Your backend is I/O-bound — database queries, external API calls, anything waiting on the network. CPU-time billing makes these workloads dramatically cheaper than Lambda.
  • You’re replacing Lambda + API Gateway for an API that handles high request volume at low CPU per request. At 10M requests/month with 15ms average CPU, Workers costs ~$5 vs Lambda’s ~$38. That gap is real.
  • You need object storage without egress fees. R2 is legitimately better than S3 for read-heavy CDN patterns, and the absence of egress charges compounds over time.
  • You’re building a simple CRUD API at modest scale. The included limits are generous enough that many low-to-mid traffic apps fit inside $5–15/month.

Watch out when:

  • You write to KV frequently. Design for read-heavy KV access patterns from the start. If you’re writing on every request, rethink the architecture before you hit scale.
  • You use D1 in any automated process — cron jobs, queue consumers, event-driven pipelines. The lack of a hard billing cap is not a theoretical risk. Add rate limiting, add billing alerts, and add a circuit breaker. Do this before the code ships.
  • Your Durable Objects hold WebSocket connections. The Hibernation API is non-negotiable for production use. Implement it from day one, not after you see the wall-clock bill.
  • Your Workers are compute-bound above ~50ms average CPU. Workers still beats Lambda in most cases, but the advantage narrows, and you’re capped at 128MB memory — which limits what you can do in-process.
  • You turn on verbose logging in production. Structured, sampled logging is not a nice-to-have; at 10M requests/month it’s a $600/month decision.

Budget rule of thumb: $15–50/month for a modest production app using Workers, KV reads, and D1. $50–200/month for write-heavy apps or apps with Durable Objects at scale. $200+ only if you’re combining several of the write-heavy patterns simultaneously or running compute-intensive workloads at very high volume.

The $5/month headline is real for I/O-heavy APIs at up to 10M requests/month. The gap between headline and actual bill is driven almost entirely by KV writes, D1 write volume, and unhibernated Durable Object duration. Understand those three meters and you can predict your bill accurately before the surprises arrive.

References