Cloudflare announced the availability of on-demand CPU and memory usage profiling for Workers and Durable Objects services, allowing developers to collect profiles from the production environment itself and display them as interactive flame graphs. The feature makes it possible to identify functions that consume CPU time or allocate the most memory, rather than relying solely on logs and aggregate metrics.
Profiling can be started from the Workers Observability page in the Cloudflare dashboard or through the command-line interface. Developers specify the profile type, CPU or memory, and the collection duration, and can also select different Worker versions. After the session ends, they can view the interactive graph and download the profile file for analysis with other tools.
What Do Flame Graphs Show?
Each rectangle in the graph represents a function call, while its width reflects the amount of CPU time or memory associated with it. Functions can be clicked to expand the focus on them, or the table view can be used to sort results by sample count. Cloudflare recommends capturing more than one profile and looking for the widest functions, while enabling source maps in TypeScript projects so that function names do not appear ambiguous.
Profiling requires selecting a deployed version that is receiving sufficient traffic; the service does not create a new isolation for measurement purposes, because the goal is to monitor actual execution in production. The following command can be used to capture a five-second CPU profile:
cf workers versions profile latest --worker-id "$WORKER_ID_OR_NAME" --duration-ms 5000 --profile-type cpu > worker-cpu.pprof
Practical Results Presented by Cloudflare
Cloudflare used the tool to analyze a Worker that implements R2 binding. The profile showed that the genericR2JsonReplacer function was traversing the JSON tree again during JSON.stringify execution, causing a nested value to be processed five times in some cases. Fixing this made the function 2.7 times faster. Profiling also revealed a repeated call to metrics, and storing and reusing the result was enough to reduce CPU consumption.
In another case, a Worker was exceeding the 128-megabyte memory limit, with P999 memory usage reaching approximately 133 megabytes and causing “Exceeded Memory” errors. The heap profile showed that the Prometheus code responsible for approximately 66.7% of allocations was still partially running despite being believed to be disabled. After removing the code path entirely, P999 fell from 133 to 118 megabytes, while P50 declined from 70 to 54 megabytes.
What Changes in Practice?
The feature gives development teams direct visibility into Workers execution under actual conditions, where traffic and isolation distribution may differ from the local development environment. The platform handles the complexity of distributing Workers across multiple data centers and devices, while developers using Durable Objects can specify the object by name to obtain a profile for the specific isolation running it.
The execution mechanism maintains request handling during collection; the isolation lock is held only when profiling starts and stops, after which CPU samples are collected at one-millisecond intervals throughout the specified duration. Durable Objects, meanwhile, benefit from their stateful nature by routing the profiling request to the isolation and owner of the specified object.
Limitations and the Next Step
Profiling does not start automatically, so the session may miss short or rare periods when a problem occurs. The memory profiler displays only allocations that occurred during the measurement window and will not necessarily capture usage resulting from startup. Cloudflare says it is working on continuous profiling, which will collect samples automatically and allow them to be viewed later from the dashboard.