Workers limits are CPU time, not wall time; waiting on fetch is free

Free: 10 ms CPU, 50 subrequests. Paid: 30 s CPU by default, 5 min via limits.cpu_ms, 10,000 subrequests. 128 MB memory everywhere. Waiting on I/O is free.

Workers

· Chapter

32

·

3

min read

The answer. The number that matters is CPU time: the milliseconds the isolate spends executing your code. Time spent awaiting fetch(), KV, D1 or a queue send does not count. Most requests use single-digit milliseconds, so the Free plan's 10 ms is less scary than it reads, and the Paid plan's default of 30 s can be raised to 5 minutes for hashing or parsing jobs. Wall time is a separate, generous limit: an HTTP invocation lives as long as the client stays connected; cron, queue and alarm handlers get 15 minutes. Memory is 128 MB per isolate on every plan, and a Worker that clones a big request body twice will find that ceiling before any CPU limit.

The pattern.

Limit Workers Free Workers Paid
CPU time per HTTP request 10 ms 5 min (default 30 s; limits.cpu_ms)
CPU time per Cron Trigger 10 ms 30 s (< 1 h interval), 15 min otherwise
Wall time, HTTP unlimited while connected unlimited while connected
Wall time, cron / queue / alarm 15 min 15 min
Memory per isolate 128 MB 128 MB
Subrequests per invocation 50 10,000 (raisable to 10M)
Simultaneous outgoing connections 6 6
Environment variables 64 per Worker, 5 KB each 128 per Worker, 5 KB each
Requests 100,000 per day unmetered
Cron Triggers per account 5 250
{ "limits": { "cpu_ms": 300000, "subrequests": 2000 } }   // Paid plan only; enforced on the network, not locally

Watch out.

  • waitUntil has its own clock: 30 s after the response, regardless of plan.
  • A redirect chain counts every hop as a subrequest; a "50 subrequests" failure often means one chatty loop.
  • Request body size is a zone-plan limit (100 MB on Free and Pro), not a Workers-plan limit.

Related: waituntil-buys-thirty-seconds-not-forever · what-a-worker-is-fetch-handler-plus-bindings · kill-switch-var-fail-closed-ceilings-fail-open