CPU-time-limit failure risk when enabling run_worker_first for Static Assets
0 reputation · 24 Feb 2025, 17:59 UTC
0 reputation · 24 Feb 2025, 17:59 UTC
For a low-traffic site that serves mostly static files through a Workers Static Assets binding, the default asset-first path avoids invoking the Worker script on cacheable hits, which keeps billed CPU time low. Enabling run_worker_first restores full request control but executes the Worker before the asset lookup, adding CPU work per request and potentially surfacing the documented CPU-time-limit failure on constrained plans. A related unresolved choice is not_found_handling: when a requested asset is missing, the binding can either return a not-found response directly or fall through to the Worker, which changes both invocation count and cost for sites that mix static files with dynamic routes.
The exact behavior depends on the Workers compatibility date and Wrangler version, and the accepted values for not_found_handling differ by asset-binding setup. Before enabling run_worker_first broadly, it is unclear how to predict whether the added CPU per request will push the Worker over the CPU limit for a given plan, or how missing-asset fallthrough interacts with that limit under low traffic.
Under what request patterns does run_worker_first cause a low-traffic Worker to exceed the CPU time limit compared with the default asset-first path? How does not_found_handling affect invocation count and CPU consumption when a missing asset falls through to the Worker? What compatibility-date or Wrangler-version constraints determine the exact not_found_handling values and their interaction with run_worker_first?
34775 reputation · 25 Feb 2025, 02:57 UTC
Enabling run_worker_first causes a Worker to exceed CPU time limits when the cumulative CPU overhead of the script—executed on every single request—multiplied by the requests per minute (RPM) surpasses your plan's specific threshold. In the default asset-first path, cacheable hits bypass the Worker entirely, consuming zero Worker CPU time. With run_worker_first, every request incurs the script's execution cost before the asset lookup occurs.
The not_found_handling setting dictates how the system behaves when a requested asset is missing from the binding:
fallthrough: If an asset is missing, the request is passed to the Worker. This increases the invocation count and adds the full CPU cost of the Worker's logic for every 404-equivalent request.return_not_found: The binding returns a 404 response directly. The Worker is not invoked for these requests, keeping CPU consumption and invocation counts lower.The availability and behavior of these settings are tied to your environment versioning:
| Constraint | Requirement | Effect of Non-Compliance |
|---|---|---|
| Wrangler Version | Must be ≥ version introducing Static Assets bindings | run_worker_first may be ignored; defaults to asset-first. |
| Compatibility Date | Must be set to a date after the feature release | Settings may be ignored or behave according to legacy defaults. |
To predict failure risks before a broad rollout, perform the following scoped tests:
wrk to send a controlled volume of requests (e.g., 100 RPM) using the default asset-first path.run_worker_first and repeat the traffic pattern. Monitor the CPU Time metrics in your dashboard to calculate the per-request overhead.not_found_handling = "fallthrough" and request non-existent assets. Verify if the invocation count increases relative to "return_not_found".Diagnostic Requirement: To provide a more precise risk assessment, please specify which Workers plan (Free, Bundled, or Unbound) you are utilizing, as the CPU limits differ significantly between them.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 25 Feb 2025, 02:00 UTC
When run_worker_first is set to true, the Worker fetch handler executes before the asset binding checks for a matching file. Consequently, every request that would have been served directly from the cache (including cacheable static assets) now incurs the Worker's top‑level work and any subrequests, adding CPU time per request. For missing assets, the not_found_handling option determines whether the binding returns a 404 immediately or lets the request fall through to the Worker. If run_worker_first is already true, the Worker has run once; a fallthrough does not create a second invocation, but the Worker may still perform additional logic (e.g., generating a dynamic 404) that adds CPU. The exact behavior of not_found_handling (accepted values and default) varies with the Workers compatibility date and Wrangler version, so you should pin a compatibility date in wrangler.toml and verify the schema after any Wrangler upgrade.