Skip to content
INTERNET INFRASTRUCTURE & NETWORKS

Cloudflare Introduces On-Demand CPU and Memory Profiling for Production Workers and Durable Objects

Understanding why an application consumes more resources than expected—whether that involves high CPU utilization or heavy memory allocation—has long presented a difficult challenge for software engineers. While traditional application logs and aggregate system metrics offer a broad overview of health and performance, they frequently fall short when developers need to isolate the exact root cause of a resource bottleneck. Standard telemetry can tell you that an application is slowing down or approaching a limit, but it rarely points directly to the offending line of code.

To bridge this visibility gap, Cloudflare has announced the official launch of native, on-demand CPU and memory profiling for Workers and Durable Objects. Accessible directly through the Workers Observability page in the Cloudflare dashboard or via the command-line interface, developers can now request real-time performance profiles of active production applications. The system renders these insights as interactive flamegraphs, and users can download the underlying profile files for deeper, offline analysis using standard diagnostic tooling.

This new capability transforms how development teams monitor and refine serverless architectures. Because the best way to understand an application’s true behavior is to observe it running in a production environment under authentic traffic conditions, this launch allows engineers to inspect live executions without relying solely on simulated local environments. Local profiling via tools like Chrome DevTools has historically been helpful, but local instances rarely replicate the complex request patterns, load volumes, and environmental nuances of global edge deployments.

To utilize the new profiling features, developers have a choice between the command-line interface and the Cloudflare dashboard. For command-line users who have the cf package installed, requesting a profile involves executing a straightforward command targeting the desired worker ID, duration, and profile type, which outputs standard .pprof files for further inspection. Alternatively, teams can navigate the Cloudflare dashboard by accessing the Workers and Pages section under the Build and Compute menu, selecting the specific worker, and opening the Observability tab.

Within the dashboard, developers can choose between CPU and memory profiling modes, select the exact script version they wish to analyze, and specify a capture duration. Because accurate profiling relies on sufficient application activity, engineers must ensure they select a deployed version experiencing active traffic. Once the capture process concludes, the interface renders an interactive flamegraph. In these visualizations, each horizontal rectangle represents a specific function call, with the width of the box corresponding directly to the amount of CPU time or memory consumed by that function. Engineers can click on individual function blocks to zoom in on specific call stacks or hover over them to review granular execution details.

Cloudflare notes that teams utilizing TypeScript should ensure that source maps are enabled for their projects before capturing profiles. Without properly configured source maps, the resulting visualizations may display obfuscated, compiled function names that are difficult to map back to original source code. For rapid initial assessments, the dashboard also provides a tabular view, allowing developers to sort functions by sample frequency and instantly identify the most heavily executed code paths.

Using CPU Profiling to Find Optimizations

Engineering teams at Cloudflare have already deployed these new profiling capabilities internally to identify optimization opportunities, resolve out-of-memory errors, and improve overall system throughput. One notable internal case study involved the optimization of the core Worker responsible for implementing the R2 storage binding. Because this application processes a massive volume of global traffic, eliminating even minor inefficiencies yields substantial performance dividends across the network.

During a 50-second CPU profiling trace of the R2 Worker, engineers examined the resulting flamegraph and identified several expected resource consumers, such as decryption routines and response byte-shifting operations, which could not be easily optimized further. However, switching to the tabular view and sorting by sample frequency revealed a less obvious bottleneck within a function called genericR2JsonReplacer.

This function accounted for more than five percent of total CPU time and exhibited recursive self-calling behavior. Although the replacer was invoked by standard JSON stringification methods on every node within a JSON tree, the function itself was also independently walking the underlying tree structure. Consequently, a data value nested five levels deep was being redundantly processed five times. Eliminating this duplicated traversal logic made the genericR2JsonReplacer function nearly three times faster.

Another optimization target surfaced during the same analysis: a duplicate call to a metrics collection function. Code inspection revealed an execution path where a metrics retrieval function was invoked once to check its length, and then invoked a second time to construct an HTTP response. Because the metrics generation logic was computationally heavy enough that a single execution consumed roughly one percent of total profile CPU time, storing the initial result in a local variable eliminated the redundant call and conserved additional processing cycles.

Introducing on-demand CPU and memory profiling with flamegraphs for Workers and Durable Objects

Resolving Memory Pressure and Evictions

In addition to CPU optimization, internal teams utilized memory profiling to diagnose and resolve severe memory pressure within a complex production Worker. The application in question suffered from a persistent operational issue: its 99.9th percentile memory utilization hovered around 133 megabytes, which frequently breached the strict 128-megabyte memory limit enforced by the runtime. These breaches triggered frequent worker evictions accompanied by "Exceeded Memory" errors.

While aggregate error logs and monitoring metrics clearly indicated that memory consumption was the underlying culprit, standard monitoring tools failed to identify which specific software components were driving up allocation totals. To uncover the source, the team captured a heap profile of a production instance and analyzed it using standard profiling parsers.

The heap profile revealed that legacy Prometheus instrumentation code accounted for approximately two-thirds of all memory allocations. Although engineers believed this instrumentation code had been disabled, remnants of the system remained partially active. Because the code actively instrumented numerous internal execution pathways across the Worker, it continued to incur heavy memory allocation costs even though the collected telemetry data was never exported or externalized.

Upon completely removing the residual Prometheus code paths, the application experienced an immediate and dramatic reduction in memory utilization across every measured percentile. Median memory consumption dropped significantly, while the 99.9th percentile metric fell safely below the platform’s execution ceiling, providing a comfortable margin of headroom and virtually eliminating memory-related worker evictions.

Profiling at the Edge and Inside Durable Objects

Executing performance profiling on distributed edge infrastructure introduces unique architectural challenges. Unlike traditional monolithic applications hosted in centralized data centers, Cloudflare Workers are globally distributed across a vast network of physical servers, routing incoming client requests to the nearest available data center to minimize network latency. Furthermore, high-traffic applications are frequently replicated across multiple physical machines within a single data center to distribute the workload.

Durable Objects introduce an additional layer of complexity because they are stateful entities with specific identities and dynamic placement rules. Before a profiling session can begin, the observability control plane must resolve several critical routing questions to locate the exact physical server, data center, and running isolate hosting the target application.

To initiate a remote session, developers or automated tooling send an application programming interface request specifying the target script name, version, duration, and profile type. Rather than spinning up a new isolated environment—which would distort performance metrics and fail to capture authentic production workloads—the profiling system targets active isolates handling live traffic.

To ensure that profiling does not disrupt user experience or application responsiveness, the Workers runtime carefully manages execution locks. The system holds the isolate lock only during essential lifecycle operations required to start and stop the profiler. Allowing application code to continue executing uninterrupted while sample data is collected ensures that the resulting performance profiles accurately reflect real-world execution characteristics.

For stateful Durable Objects, the runtime leverages the object’s unique identifier to route the profiling request directly to the precise physical metal and isolate currently maintaining that specific actor instance. This enables engineers to capture targeted profiles of individual stateful components anywhere across the global network.

Next Steps and Future Improvements

While on-demand profiling provides unprecedented visibility into production performance, the current implementation has certain limitations, notably the requirement for sufficient live traffic to capture meaningful sample distributions during active profiling windows. To address these constraints and simplify diagnostics for intermittent or rare runtime events, Cloudflare is actively developing continuous profiling capabilities. This upcoming feature will automatically capture profiling samples in the background, allowing developers to review historical performance data directly within the dashboard without manually initiating individual capture sessions.

Leave a Reply

Your email address will not be published. Required fields are marked *