shiichan

On-Demand CPU and Memory Profiling with Flamegraphs Comes to Workers and Durable Objects

Hi, it's Shii-chan! Today we have a feature Workers developers may have been waiting for: profiling a Worker running in production, right on demand!

Cloudflare Blog blog.cloudflare.com

What was announced?

The Cloudflare Blog announced on-demand CPU and memory profiling for Workers and Durable Objects.

You can capture a profile of a running Worker in production, view it as an interactive flamegraph, and download the profile file for further analysis. Profiles are accessed from the Workers Observability page.

The story so far

The post frames the problem as tracking down memory leaks and performance bottlenecks in production. This feature lets you get at them directly from real production execution.

What changes

Here is how to read a flamegraph:

  • Each rectangle is a function call
  • Width shows the CPU time or memory attributed to that function
  • Click a function to focus on it, hover for details
  • A table view sorts functions by sample count, which helps surface less visible hotspots

Cloudflare shared a few examples from its own use:

  • CPU (a Worker using an R2 binding): genericR2JsonReplacer used over 5% of CPU. Its recursive walk repeated work already done by JSON.stringify, so a nested value was processed once per level. Removing the duplication made the function 2.7x faster. A repeated metrics call using about 1% of CPU was also reduced by storing its result once
  • Memory: a Worker's P999 memory was about 133 MB against a 128 MB limit, causing "Exceeded Memory" evictions. A heap profile showed that Prometheus instrumentation, which was supposed to be disabled, accounted for roughly 66.7% of allocations. Removing it lowered P999 to 118 MB and P50 from 70 MB to 54 MB

Dive Deep

There are three ways to use it:

  • CLI: with the cf package installed, this captures a 5-second CPU profile of the latest version
cf workers versions profile latest --worker-id "$WORKER_ID_OR_NAME" --duration-ms 5000 --profile-type cpu > worker-cpu.pprof
  • API: send a request to the account's Workers versions endpoint for the latest version's /profile path, with a JSON body that sets duration_ms and profile_type
  • Dashboard: go to Build → Compute → Workers & Pages, select your Worker, open the Observability tab, and choose "Flamegraph" from the dropdown. Pick CPU or memory, a duration, and a version, then click Capture Profile

TypeScript Workers need source maps enabled, or function names may look obfuscated. Capturing a few profiles and comparing the widest functions is recommended.

A few architecture notes:

  • A profiling request must resolve the requested version, the data center where it recently ran, whether its isolate is still loaded, and whether the isolate belongs exclusively to the requesting account
  • For Durable Objects, the request is routed by object name to the physical server that owns the live object
  • No new isolate is started; profiling observes real production execution, so low-traffic Workers may be hard to profile
  • For CPU profiles, the runtime holds the isolate lock only for setup and teardown. It samples at a 1 ms interval while requests keep running, then serializes the result outside the lock

There are limits too:

  • Profiling must be started manually, so intermittent problems outside the capture window can be missed
  • The memory profiler only shows allocations made during the capture window, not during startup
  • The chosen version needs enough traffic to be profiled
  • Continuous profiling, which would capture samples automatically, is in development

The post does not mention pricing.

Wrap-up

  • Capture CPU and memory profiles of Workers and Durable Objects on demand in production
  • View them as flamegraphs and download the profile
  • Available from the dashboard, the CLI, and the API
  • Limits include manual start, no startup allocations, and a need for traffic
  • Continuous profiling is in development

If your Worker is slow or running into memory limits, you'll want to try this first thing next week!